将DataTable转换为通用列表? [英] Convert DataTable to generic List?
问题描述
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;
}
我们现在唯一可以想到的是我们必须做我们需要垃圾收集我们的东西?
Thats the only thing we can think of right now is that we must be doing something where we need to Garbage collect Ourselves?
想法?
为什么我们认为可能会有泄漏? :
Why we think there might be a leak?:
我们的内存不足错误。如果一个页面不需要业务逻辑来使用这种类型的转换,则II6进程不会增长,但是当我们打到使用它的页面时,它会增长。
We are getting Out of Memory Errors. If a Page does not require business logic to use this type of conversion, the II6 process does not grow, but when we hit a page that uses it, it grows.
我们正在获得ANTS Profiler给我们更多的细节。
We are currently getting ANTS Profiler to give us more details.
推荐答案
p>这不会是一个实际的泄漏,但它可能会不必要地强调事物...
That won't be an actual leak, but it could be stressing things unnecessarily...
你正在处理多少行?
请注意,反射是一种痛苦,每次调用诸如 GetCustomAttributes
的东西都可以返回一个新的数组(所以你想做一次,而不是一次,属性每行)
How many rows are you working over?
Note that reflection is a pain, and that every call to things like GetCustomAttributes
can return a new array (so you want to do that once, not once per-property-per-row).
个人而言,我将预先构建我打算做的工作...如下所示。
Personally, I'd pre-construct the work I intend to do... something like below.
请注意,如果我这样做很多,我可以切换到 HyperDescriptor ,或者如果.NET 3.5是一个选项,也可能是编译的表达式。由于 DataTable
不是强类型,所以 HyperDescriptor
将在下面的一个逻辑下一步(性能)。
Note that if I was doing this lots, I'd either switch to HyperDescriptor, or if .NET 3.5 was an option, maybe a compiled Expression. Since DataTable
isn't strongly typed, HyperDescriptor
would be a logical next step (for performance) after the below...
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;
}
这篇关于将DataTable转换为通用列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!