5

这是一个“让我们看看能不能完成”的练习。

假设我有一个包含几列的 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 集合。

我希望我已经足够清楚地解释了这一点。在玩了一点之后,我开始认为,就可读性和可维护性而言,我想出的任何东西都会是一团糟,但我想我会问。

4

2 回答 2

4

恐怕没有这样的魔法(至少没有匿名类型)。匿名类型是由编译器生成为不可变类的隐式类型,其属性由显式赋值操作命名和键入,如第二个示例中(在编译时)。

您想要做的将需要在运行时构造的动态类型。

于 2011-06-15T20:32:20.650 回答
2

正如 Brandon 的回答中已经确定的那样,这不能用 Anonymous 类型来完成,因为它们是在编译时生成的。但是,如前所述,您可以利用动态来获得类似的语法。

例如,您可以获得以下语法(基于您的示例):

var seq = table.AsEnumerable().Select(row => (dynamic)new DynamicDataRow(row));
foreach (var s in seq)
{
    Console.WriteLine(s.Column1);
    Console.WriteLine(s.Column2);
    Console.WriteLine(s.Column3);
}

为您的 DataRows 使用简单的动态包装器:

class DynamicDataRow : DynamicObject
{
    private readonly DataRow row;

    public DynamicDataRow(DataRow row)
    {
        this.row = row;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        DataColumn column = row.Table.Columns[binder.Name];
        if (column != null)
        {
            result = row[column];
            return true;
        }

        result = null;
        return false;
    }
}

我不确定您的用例是什么,但如果您认为动态是匿名类型的可接受替代品,希望这有助于为您指明正确的方向。

于 2014-02-20T02:06:17.353 回答