如何在C#中将DataTable行复制到对象中?

3

For example, I have an object of class:

class MyClass
{
public int a { get; set; }
public string b { get; set; }
public DateTime c { get; set; }
}

我有一个 DataTable 对象,其中的列与 MyClass 中的列同名。是否有一种快速简单的方法将 DataTable 对象的每行复制到 MyClass 对象中。

就像这样(但在我的情况下,列太多了):

for (int x = 0; x < dataTableObj.Rows.Count; x++)
{
myClassObj[x].a = dataTableObj.Rows[x]["a"];
myClassObj[x].b = dataTableObj.Rows[x]["b"];
myClassObj[x].c = dataTableObj.Rows[x]["c"];
}

谢谢您的支持。

1
如果您的数据表中的列与类中的属性名称完全相同,您可以使用“反射”... - Dave Zych
为什么不使用EF或Linq2SQL,直接将您的类映射到数据库表呢? - Mithrandir
为什么你在 myClassObj 中已经有了 dataTable.Rows.Count 个对象?我会使用 List<MyClass> 并在 foreach 中添加一个新实例。顺便说一句,反射总是比手动创建实例更慢且容易出错。 - Tim Schmelter
是的,我需要超级快速的性能。 - Oomph Sonar
@HariSeldon 如果有区别,那也是微不足道的,甚至可以忽略不计。 - Servy
显示剩余4条评论
2个回答

5
为了达到这个目的,我使用以下方法,数据表的列和类型属性应该具有相同的名称。
public static List<T> TableToList<T>(DataTable table)
{
  List<T> rez = new List<T>();
  foreach (DataRow rw in table.Rows)
  {
    T item = Activator.CreateInstance<T>();
    foreach (DataColumn cl in table.Columns)
    {
      PropertyInfo pi = typeof(T).GetProperty(cl.ColumnName);

      if (pi != null && rw[cl] != DBNull.Value)
      {
        var propType = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;
        pi.SetValue(item, Convert.ChangeType(rw[cl], propType), new object[0]);
      }

    }
    rez.Add(item);
  }
  return rez;
}

非常感谢,你是我的救星。我正在维护遗留代码,我能够快速将DataTable转换为对象列表。现在我的问题是关于性能的,我们都知道反射不如其他方法高效,当处理大量数据时是否会遇到任何问题? - a.boussema
很好,你可以放弃反射并为你使用的每个类制作专门的方法。但请在更改之前对该代码进行分析,只有这样你才能确定哪些是慢的。 - Antonio Bakula
1
我在这里提供一些处理 Nullable 的技巧:在传递给 Convert.ChangeType 之前,请执行以下操作并将 pi.PropertyType 更改为 t: Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType; - a.boussema

3
你应该可以修改以下代码以满足你的需求。
var myBindings = System.Reflection.BindingFlags.Instance
        | System.Reflection.BindingFlags.Public 
        | System.Reflection.BindingFlags.SetProperty;

foreach (var row in table.AsEnumerable())
{
    MyClass newObject = new MyClass();
    foreach (var property in typeof(MyClass).GetProperties(myBindings))
    {
        if (table.Columns.Contains(property.Name))
        {
            //optionally verify that the type of the property matches what's in the datatable
            property.SetValue(newObject, row[property.Name]);
        }
    }
    //add newObject to result collection
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接