使用Linq连接动态数据表

使用Linq连接动态数据表,linq,datatable,dynamic-data,Linq,Datatable,Dynamic Data,我有两个列是动态的数据表,它们都有一个公共列。 现在我想连接这两个表。 得到综合结果 提前感谢。一个简单的方法是在表上使用AsEnumerable(),并在公共列数据上连接它们 假设您的表如下所示:[Table1]->[ID][Name][Location]|[Table2]->[ID][Description],ID列具有相同的值 DataTable table1 = new DataTable(); table1.Columns.Add("ID", typeof(int)); table1

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


提前感谢。

一个简单的方法是在表上使用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

不使用
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);
公共扩展对象组合(数据行r1、数据行r2)
{
动态x=新的ExpandooObject();
x、 ID=r1.字段(“ID”);
x、 名称=r1.字段(“名称”);
//使用Expando作为字典
IDictionary xd=(IDictionary)x;
//枚举所有非ID和名称列的两行,并添加到Expando
foreach(r1.Table.Columns中的数据列c)
if(c.ColumnName!=“ID”&&c.ColumnName!=“Name”)
xd.Add(c.ColumnName,r1[c]);
foreach(r2.Table.Columns中的数据列c)
if(c.ColumnName!=“ID”&&c.ColumnName!=“Name”)
xd.Add(c.ColumnName,r2[c]);
返回x;
}
/// .... 再往下
var p=来自表1中的a.AsEnumerable()
在表2中加入b。a.Field(“ID”)上的AsEnumerable()等于b.Field(“ID”)
选择组合(a、b);
linq中的select与SQL select并不完全相同,它只是为转换提供了一个占位符,可以是简单的、复杂的,甚至是外部调用代码


注意:如果您不想使用dynamic,那么同样可以通过首先枚举两个表中的所有列并创建第三个表来制定解决方案。然后将CombineMe更改为生成
DataRow
,而不是
ExpandooObject
,最后枚举p,并将其所有条目(数据行的组合实例)添加到结果表中

您好,您可能希望连接运行时生成的两个数据表。查看此链接。可能对你有用


当你说“带有动态列的数据表”时,你的确切意思是什么?它是非类型化的
DataTable
,是
expandooobject
DynamicObject
派生实例的列表,还是完全不同的东西?实际上,存储过程将返回两个ID为,名称为两个表中的公共列。这两个表的列数相同,但列名不同。我们需要合并这两个表。实际上,我需要两个表中的所有列,并且只需要一个公共列。在select语句中,我不想在select new{}中提及特定列