动态数据表加入使用Linq

时间:2011-03-11 06:21:21

标签: linq datatable dynamic-data

我有两个数据表,其列是动态的,并且它们都有一个公共列。 现在我想加入这两个表。 得到综合结果。

提前致谢。

3 个答案:

答案 0 :(得分:3)

您好,您可能希望加入在运行时生成的两个数据表。看看这个链接。可能对你有用

Finding common columns from two datatable and using those for Join condition in LINQ

答案 1 :(得分:0)

一种简单的方法是在表上使用AsEnumerable()并将它们连接到公共列数据上。

假设您的表格如下:[Table1] -> [ID] [Name] [Location] | [Table2] -> [ID] [Description]且ID列具有相同的值


DataTable table1 = new DataTable();
table1.Columns.Add("ID", typeof(int));
table1.Columns.Add("Name", typeof(string));
table1.Columns.Add("Location", typeof(string));
table1.Rows.Add(1, "Name1", "Location1");
table1.Rows.Add(2, "Name2", "Location2");
table1.Rows.Add(3, "Name3", "Location3");

DataTable table2 = new DataTable();
table2.Columns.Add("ID", typeof(int));
table2.Columns.Add("Description", typeof(string));
table2.Rows.Add(1, "Description1");
table2.Rows.Add(2, "Description2");
table2.Rows.Add(3, "Description3");

然后您只需要加入ID列上的表格并选择结果数据集


var joinedTables = from data1 in table1.AsEnumerable()
                   join data2 in table2.AsEnumerable() on data1.Field("ID") equals data2.Field("ID")
                   select new {  id= data1.Field("ID"), 
                     name = data1.Field("Name"), 
                     loc = data1.Field("Location"),
                     desc = data2.Field("Description")
                   }; 

结果数据:

id name  loc       desc
1  Name1 Location1 Description1
2  Name2 Location2 Description2
3  Name3 Location3 Description3

答案 2 :(得分:0)

如果不使用ExpandoObject就不那么容易,因为LINQ通常被调整为生成强类型对象,您需要在编译时知道模式。我发现这种情况的方法是通过转换调用组合方法,其中方法将生成一个动态对象,其中包含所有已发现字段的组合

public ExpandoObject CombineMe(DataRow r1, DataRow r2) 
{
    dynamic x = new ExpandoObject();
    x.ID = r1.Field<int>("ID");
    x.Name = r1.Field<string>("Name");

    // use Expando as dictionary
    IDictionary<String, Object> xd = (IDictionary<String, Object>)x;

    // enumerat both rows for all columns not ID and Name and add to Expando
    foreach (DataColumn c in r1.Table.Columns) 
        if (c.ColumnName != "ID" && c.ColumnName != "Name") 
            xd.Add(c.ColumnName, r1[c]);
    foreach (DataColumn c in r2.Table.Columns)
        if (c.ColumnName != "ID" && c.ColumnName != "Name")
            xd.Add(c.ColumnName, r2[c]);
    return x;
}

/// .... further down

var p = from a in table1.AsEnumerable()
        join b in table2.AsEnumerable() on a.Field<int>("ID") equals b.Field<int>("ID")
        select CombineMe(a, b);

在linq中选择并不完全像SQL select,它只是提供一个转换占位符,简单,复杂甚至是外部调用代码。

注意:如果您不想使用动态,则可以通过首先枚举两个表中的所有列并创建第三个表来类似地制作解决方案。然后将CombineMe更改为生成DataRow而不是ExpandoObject,最后枚举p并将其所有条目(DataRow的组合实例)添加到结果表中。