如何高效的将 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);
        }

Guess you like

Origin blog.csdn.net/mzl87/article/details/121355537