2011-03-11 55 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的組合實例)添加到結果表中。