public static IList<T> ConvertTo<T>(DataTable table) { if (table == null) { return null; } List<DataRow> rows = new List<DataRow>(); foreach (DataRow row in table.Rows) { rows.Add(row); } return ConvertTo<T>(rows); } public static T ConvertItem<T>(DataTable table) { T obj = default(T); if (table != null && table.Rows.Count > 0) { obj = CreateItem<T>(table.Rows[0]); } return obj; } public static T CreateItem<T>(DataRow row) { T obj = default(T); if (row != null) { obj = Activator.CreateInstance<T>(); Type entityType = typeof(T); PropertyInfo[] properties = entityType.GetProperties(); for (int i = 0; i < properties.Length; i++) { object[] customAttributes = properties[i].GetCustomAttributes(typeof(ColumnAttributes),false); ColumnAttributes dataField = null; if (null != customAttributes && customAttributes.Length > 0 && null != (dataField = customAttributes[0] as ColumnAttributes)) { if (row.Table.Columns.Contains(dataField.FieldName) && !row[dataField.FieldName].GetType().FullName.Equals("System.DBNull")) { properties[i].SetValue(obj,row[dataField.FieldName],null); } } } } return obj; }
那就是我们现在唯一能想到的就是我们必须做一些我们需要垃圾收集的事情吗?
思考?
为什么我们认为可能存在泄漏?:
我们正在失去内存错误.如果一个页面不需要业务逻辑来使用这种类型的转换,那么II6进程就不会增长,但是当我们点击一个使用它的页面时,它就会增长.
我们目前正在获取ANTS Profiler以向我们提供更多详细信息.
解决方法
这不会是一个实际的泄漏,但它可能会不必要地强调事情……
你工作了多少行?
请注意,反射是一种痛苦,每次调用GetCustomAttributes之类的东西都可以返回一个新数组(所以你想要这样做一次,而不是每行每个属性一次).
就个人而言,我预先构建了我打算做的工作……如下所示.
请注意,如果我这样做,我要么切换到HyperDescriptor,或者如果.NET 3.5是一个选项,可能是一个已编译的表达式.由于DataTable不是强类型的,因此HyperDescriptor将是下面的逻辑下一步(性能)…
sealed class Tuple<T1,T2> { public Tuple() {} public Tuple(T1 value1,T2 value2) {Value1 = value1; Value2 = value2;} public T1 Value1 {get;set;} public T2 Value2 {get;set;} } public static List<T> Convert<T>(DataTable table) where T : class,new() { List<Tuple<DataColumn,PropertyInfo>> map = new List<Tuple<DataColumn,PropertyInfo>>(); foreach(PropertyInfo pi in typeof(T).GetProperties()) { ColumnAttribute col = (ColumnAttribute) Attribute.GetCustomAttribute(pi,typeof(ColumnAttribute)); if(col == null) continue; if(table.Columns.Contains(col.FieldName)) { map.Add(new Tuple<DataColumn,PropertyInfo>( table.Columns[col.FieldName],pi)); } } List<T> list = new List<T>(table.Rows.Count); foreach(DataRow row in table.Rows) { if(row == null) { list.Add(null); continue; } T item = new T(); foreach(Tuple<DataColumn,PropertyInfo> pair in map) { object value = row[pair.Value1]; if(value is DBNull) value = null; pair.Value2.SetValue(item,value,null); } list.Add(item); } return list; }