如何在泛型方法内有效地创建对象列表
本文关键字:有效地 创建对象 列表 泛型方法 | 更新日期: 2023-09-27 18:32:10
所以,我有一个位于数据库上的应用程序。到目前为止,我的查询结果都进入了一个 DataTable 对象,如下所示:
DataTable data = new DataTable();
data.Load(someQuery.ExecuteReader());
现在,我想将数据加载到强类型对象的列表中。像这样:
List<MyClass> data = someQuery.Load<MyClass>();
然而,我第一次尝试编写该方法最终运行的速度几乎比DataTable.Load(IDataReader)方法慢三倍。基本上,我有用户GetConstructor(null)。Invoke(null) 来创建和对象,我使用了 PropertyInfo.SetValue(reader.GetValue()) 来填充数据。
有没有更好的方法可以做到这一点?
使用的方法:
public List<T> LoadData<T>(DbCommand query)
{
Type t = typeof(T);
List<T> list = new List<T>();
using (IDataReader reader = query.ExecuteReader())
{
while (reader.Read())
{
T newObject = (T)t.GetConstructor(null).Invoke(null);
for (int ct = 0; ct < reader.FieldCount; ct++)
{
PropertyInfo prop = t.GetProperty(reader.GetName(ct));
if (prop != null)
prop.SetValue(newObject, reader.GetValue(ct), null);
}
list.Add(newObject);
}
}
return list;
}
为了有效地做到这一点,需要元编程。您可以使用库来提供帮助。例如,"FastMember"包括一个TypeAccessor,它提供对实例创建和按名称进行成员访问的快速访问。然而,这个例子基本上也是"dapper"的工作原理,所以你可以只使用dapper:
int id = ...
var data = connection.Query<Order>(
"select * from Orders where CustomerId = @id",
new { id }).ToList();
您还可以打开"dapper"代码以查看它的作用。
您可以使用 linQ 执行查询并获取泛型列表,然后如果要将其转换为 DataTable,请使用以下代码,它可能会对您有所帮助。
public DataTable ListToDataTable<T>(IEnumerable<T> list)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (T item in list)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
return table;
}
它适用于任何强类型类。请检查执行所需的时间。
谢谢