[英]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.