繁体   English   中英

将datatable对象转换为列表C#

[英]Convert datatable object to list C#

我在stackoverflow上找到了以下代码。 但是我没有从根本上得到这段代码在做什么。 谁能解释一下此代码的工作原理?

public static List<T> ToListof<T>(DataTable dt)
    {
        const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
        var columnNames = dt.Columns.Cast<DataColumn>()
            .Select(c => c.ColumnName)
            .ToList();
        var objectProperties = typeof(T).GetProperties(flags);
        var targetList = dt.AsEnumerable().Select(dataRow =>
        {
            var instanceOfT = Activator.CreateInstance<T>();

            foreach (var properties in objectProperties.Where(properties => columnNames.Contains(properties.Name) && dataRow[properties.Name] != DBNull.Value))
            {
                properties.SetValue(instanceOfT, dataRow[properties.Name], null);
            }
            return instanceOfT;
        }).ToList();

        return targetList;
    }

我特别想知道coloumn的数据在哪里进行类型转换。 我已经搜索了许多链接,但在任何地方都找不到正确的答案。

它尝试在运行时动态地将数据表转换为类型T的对象列表。

var objectProperties = typeof(T).GetProperties(flags);

该行使用反射来获取类型T上的公共属性的列表。

var targetList = dt.AsEnumerable().Select(dataRow =>

该行将DataTable迭代为IEnumerable,为每一行获取一个名为dataRow的实例。

var instanceOfT = Activator.CreateInstance<T>();

这将在循环内部使用反射创建类型T的新实例。 这意味着将为每个dataRow创建一个新的T。

foreach (var properties in objectProperties.Where(properties => 
                  columnNames.Contains(properties.Name) 

这遍历了我们一开始就获得的T的所有属性,这些属性也包含在columnNames -意味着有一列具有它们的值

  && dataRow[properties.Name] != DBNull.Value))

条件的后半部分确保该列具有值并且不为NULL。

  properties.SetValue(instanceOfT, dataRow[properties.Name], null);

再次使用反射,将数据行中的值设置为T的属性。

).ToList();

这将接受从Select语句返回的所有项目,并从中返回一个列表。

代码并不是最整洁的,但是如果您知道反射是如何工作的,则这些变量的名称就很清楚。 至于第二个问题-没有强制转换,因为此代码假定DataRow中的值的类型与属性的类型匹配。 否则,将引发异常。

详细:

const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

这将结合public和instance标志,以便仅搜索Public非静态方法。

 var columnNames = dt.Columns.Cast<DataColumn>()
    .Select(c => c.ColumnName)
    .ToList();

这将列出数据表中的所有列名称

var objectProperties = typeof(T).GetProperties(flags);

获取通用参数的类型,并将列出所有公共的非静态属性

dt.AsEnumerable().Select

为DataTable中的每个数据行创建一个IEnumerable

var instanceOfT = Activator.CreateInstance<T>();

这将创建一个新实例,就像您将使用new

 foreach (var properties in objectProperties.Where(properties => columnNames.Contains(properties.Name) && dataRow[properties.Name] != DBNull.Value))
 {
     properties.SetValue(instanceOfT, dataRow[properties.Name], null);
 }

这将遍历T whos的所有属性,这些属性也包含在数据表中并且不为null(例如,数据库中的DbNull)

然后调用SetValue。 由于dataRow已将其返回的值存储在数据库中,因此没有强制转换。 仅当属性和数据库中的类型“相同”时,此方法才有效。 作为NVarchar的字符串。

暂无
暂无

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

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