【发布时间】:2014-02-20 10:06:17
【问题描述】:
这是一个“让我们看看能不能完成”的练习。
假设我有一个包含几列的 DataTable。使用 linq,是否可以选择表的行,使得结果将是匿名类型的序列,其中匿名类型的每个属性根据 DataTable 的列名命名并设置每个属性的类型适当的。
所以如果我的 DataTable 有三列像这样:
Name = "Column1", DataType = string
Name = "Column2", DataType = integer
Name = "Column3", DataType = bool
然后我想选择DataTable的所有行,使得匿名类型具有三个属性:
DataSet ds = functionThatGetsADataSet();
var seq = ds.Tables[0].AsEnumerable().Select( r => **** MAGIC HERE ****)
foreach (var s in seq)
{
Console.WriteLine(s.Column1);
Console.WriteLine(s.Column2);
Console.WriteLine(s.Column3);
}
我知道我可以做到:
DataSet ds = functionThatGetsADataSet();
var seq = ds.Tables[0].AsEnumerable().Select( r =>
new
{
Column1 = r.Field<string>("Column1"),
Column2 = r.Field<int>("Column2"),
Column3 = r.Field<bool>("Column3"),
}
)
foreach (var s in seq)
{
Console.WriteLine(s.Column1);
Console.WriteLine(s.Column2);
Console.WriteLine(s.Column3);
}
但这需要在 new 子句中对属性名称进行硬编码,而我希望属性名称来自 DataTable 的 Columns 集合。
我希望我已经足够清楚地解释了这一点。在玩了一会儿之后,我开始认为,就可读性和可维护性而言,我想出的任何东西都会是一团糟,但我想我会问。
【问题讨论】:
-
匿名类型是一种编译时机制,它不会等到运行时才描述自己。但是假设您可以解决这个问题,您可以让运行时找出您的属性名称和类型并围绕它构建一个类型。你将如何在编译时使用它?说实话,如果你处于这种困境中,要么保留
DataTable,要么花时间正确定义类型(匿名或其他)。
标签: c# linq anonymous-types system.data.datatable