如何高效的将 DataReader 转成 List<T; ?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何高效的将 DataReader 转成 List<T; ?相关的知识,希望对你有一定的参考价值。

咨询区

  • Anthony

我在使用第三方工具包,它返回了一个 DataReader,为了能更方便的使用,我希望有一种快捷方法能够将它转成 List<T>,除了一行一行的迭代赋值之外还有其他好的方式吗?

回答区

  • pim

可以用反射实现,虽然性能低一点,但它可以帮你自动化的将 DataReader 映射到 List<T> 上,这里的 T 可以是你的任意类型,参考如下代码:

public static class DataRecordHelper
{
    public static void CreateRecord<T>(IDataRecord record, T myClass)
    {
        PropertyInfo[] propertyInfos = typeof(T).GetProperties();

        for (int i = 0; i < record.FieldCount; i++)
        {
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                if (propertyInfo.Name == record.GetName(i))
                {
                    propertyInfo.SetValue(myClass, Convert.ChangeType(record.GetValue(i), record.GetFieldType(i)), null);
                    break;
                }
            }
        }
    }
}

public class Employee
{
    public int Id { get; set; }
    public string LastName { get; set; }
    public DateTime? BirthDate { get; set; }

    public static IDataReader GetEmployeesReader()
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);

        conn.Open();
        using (SqlCommand cmd = new SqlCommand("SELECT EmployeeID As Id, LastName, BirthDate FROM Employees"))
        {
            cmd.Connection = conn;
            return cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }

    public static IEnumerable GetEmployees()
    {
        IDataReader rdr = GetEmployeesReader();
        while (rdr.Read())
        {
            Employee emp = new Employee();
            DataRecordHelper.CreateRecord<Employee>(rdr, emp);

            yield return emp;
        }
    }
}
  • Phil Cooper

对于你的需求,建议使用 Dapper 做这种映射,参考如下代码:

public List<CustomerEntity> GetCustomerList()
{
    using (DbConnection connection = CreateConnection())
    {
        return connection.Query<CustomerEntity>("procToReturnCustomers", commandType: CommandType.StoredProcedure).ToList();
    }
}

CreateConnection() 它用来创建数据库连接,然后 Dapper 内部会通过 ILEmit 的方式实现 DataReader 和 Properties 之间的自动映射,非常方便。

  • Mohsen

我有一个好办法,既不需要引用 ORM 组件,也不需要手工写反射,借助 DataTable 和 JsonConvert 即可, 参考如下代码:

public static void Main()
        {
            var dt = new DataTable();
            dt.Load(yourDataReader);
            // creates a json array of objects
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(dt);
            // this is what you're looking for right??
            List<YourEntityType> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<YourEntityType>>(json);
        }

点评区

我个人在开发中,数据库用 Dapper ,DTO之间用 AutoMapper,非常方便,大家可以参考参考。

以上是关于如何高效的将 DataReader 转成 List<T; ?的主要内容,如果未能解决你的问题,请参考以下文章

如何轻松将 DataReader 转换为 List<T>? [复制]

如何正确地将 DataReader 转换为 DTO/List<DTO>? [复制]

java中怎么list 转成 map

方便的将数字转成字符串类型并在前面补0

c#如何将查询后的结果放入list中

我应该如何测试从 DataReader 填充列表的方法?