Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在泛型方法内部高效地创建对象列表?_C#_Generics_Reflection_Ado.net - Fatal编程技术网

C# 如何在泛型方法内部高效地创建对象列表?

C# 如何在泛型方法内部高效地创建对象列表?,c#,generics,reflection,ado.net,C#,Generics,Reflection,Ado.net,所以,我有一个数据库上的应用程序。到目前为止,我的查询结果都进入了DataTable对象,如下所示: DataTable data = new DataTable(); data.Load(someQuery.ExecuteReader()); List<MyClass> data = someQuery.Load<MyClass>(); 现在,我想将数据加载到强类型对象的列表中。大概是这样的: DataTable data = new DataTable(); da

所以,我有一个数据库上的应用程序。到目前为止,我的查询结果都进入了DataTable对象,如下所示:

DataTable data = new DataTable();
data.Load(someQuery.ExecuteReader());
List<MyClass> data = someQuery.Load<MyClass>();
现在,我想将数据加载到强类型对象的列表中。大概是这样的:

DataTable data = new DataTable();
data.Load(someQuery.ExecuteReader());
List<MyClass> data = someQuery.Load<MyClass>();
List data=someQuery.Load();
然而,我编写该方法的第一次尝试最终运行速度几乎是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;
    }
公共列表加载数据(DbCommand查询)
{
类型t=类型(t);
列表=新列表();
使用(IDataReader=query.ExecuteReader())
{
while(reader.Read())
{
T newObject=(T)T.GetConstructor(null).Invoke(null);
对于(int-ct=0;ct
您可以使用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;
    }
公共数据表列表到数据表(IEnumerable列表)
{
PropertyDescriptorCollection属性=
GetProperties(typeof(T));
DataTable=新的DataTable();
foreach(属性中的PropertyDescriptor属性)
table.Columns.Add(prop.Name,Nullable.GetUnderlyingType(prop.PropertyType)??prop.PropertyType);
foreach(列表中的T项)
{
DataRow行=table.NewRow();
foreach(属性中的PropertyDescriptor属性)
行[prop.Name]=prop.GetValue(项)??DBNull.Value;
table.Rows.Add(行);
}
返回表;
}
它适用于任何强类型的类。请检查执行所需的时间


谢谢,

要有效地执行此操作,需要元编程。您可以使用库来提供帮助。例如,“FastMember”包括一个TypeAccessor,它提供对实例创建的快速访问和按名称访问的成员。然而,这个例子也基本上就是“dapper”的工作原理,所以您可以使用dapper:

intid=。。。
var data=connection.Query(
“从CustomerId=@id的订单中选择*”,
新的{id}).ToList();

您还可以打开“简洁”代码来查看它的功能。

反射无疑是缓慢的。“强类型”指的是
MyClass
始终,也可以是任何类型,例如
T
?您可以发布代码以加载到强类型对象列表中吗?可以使用任何类。当然,类属性必须与数据相匹配。从来都不知道它的存在。作者声称有速度,我将对其进行测试。@Nezreli是的,我确实声称有速度:)我们在Stack Exchange上专门编写了dapper,将性能作为关键衡量标准。我们对它进行了优化,直到它发出吱吱声,这基本上是因为我们有“相当多”的数据访问。谢谢。我面对一张300米以上的桌子。我需要所有我能得到的帮助来管理它。@Nezreli我想你有很好的理由将300M加载到内存中。但这不是通常的情况。@Nezreli即使有200多个用户,这通常也不意味着“加载所有数据”——例如,堆栈溢出的用户比这多得多——但我们不会加载整个数据库。但是:我假设你有一个设计需要它。祝你好运