繁体   English   中英

如何有效地在通用方法内部创建对象列表?

[英]How to efficiently create a list of objects inside of a generic method?

因此,我有一个位于数据库上的应用程序。 到目前为止,我的查询结果都进入了这样的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;
    }

它适用于任何强类型类。 请检查执行时间。

谢谢,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM