2011-03-11 51 views
3

我有两个数据表的列是动态的,它们都有一个公共列。 现在我想加入这两张表。 获取综合结果。动态数据表加入使用Linq

在此先感谢。

+0

有用的,你到底是什么意思?它是无类型的'DataTable',它是'ExpandoObject'或'DynamicObject'派生实例的列表,还是完全不同的东西? – mmix 2011-03-11 10:45:56

+0

其实一个存储过程将返回两个ID为ID的表,Name作为两个表中的公共列。它们将具有相同的列数,但列名不同。我们需要组合这两个表 – 2011-03-11 12:00:57

回答

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 
+0

Acrtally我需要所有列来自这两个表和只有一个共同的列。在选择声明中,我不想在选择新{ – 2011-03-11 11:48:09

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选择,它只是提供了一个简单,复杂甚至是外部调用代码的转换占位符。

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