2015-08-27 24 views
0

我需要你的幫助,一個小問題。我想使下面的LINQ查詢成爲動態的(在運行時),因爲我不知道數據庫中會有多少表(表名在運行時是已知的)。c#動態LINQ查詢在運行時數據集

var query = from row1 in ds.Tables["tab1"].AsEnumerable() 
     from row2 in ds.Tables["tab2"].AsEnumerable() 
     from row3 in ds.Tables["tab3"].AsEnumerable() 
     select new { row1, row2, row3 }; 

在這種情況下,生成動態LINQ查詢並將結果寫入數據表或數組可能嗎?

在此先感謝!

+0

所以,你要的所有錶行的笛卡爾積? –

+0

是蒂姆那就是我想要的 – derchrome

回答

1

This extension method可以在DataSet中創建所有表格行的笛卡爾積。

public static class Extensions 
{ 
    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
    { 
     IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() }; 
     return sequences.Aggregate(
      emptyProduct, 
      (accumulator, sequence) => 
       from accseq in accumulator 
       from item in sequence 
       select accseq.Concat(new[] { item }) 
      ); 
    } 
} 

現在你可以以這種方式使用它:

IEnumerable<IEnumerable<DataRow>> allTablesRows = ds.Tables.Cast<DataTable>() 
    .Select(table => table.AsEnumerable()) 
    .CartesianProduct(); 

輸出:

foreach (var x in allTablesRows) 
{ 
    foreach (DataRow row in x) 
    { 
     Console.WriteLine("table:{0} fields:{1}", 
      row.Table.TableName, 
      string.Join(",", row.ItemArray)); 
    } 
} 
+0

令人印象深刻!非常感謝你TIM! – derchrome

+0

還有一個問題:我在推理中遇到了一個小錯誤:-)每個表都有一個ID作爲第一列。我只需要將那些在開始時具有相同ID的行/表相乘......是否可以添加「where」語句? – derchrome

+0

也許這會有助於在你的問題中提供一個小例子。或者 - 因爲問題發生了變化 - 問另一個問題。你想加入具有相同ID的行嗎?或者你想要在其他表中出現ID的所有行的笛卡爾積?它變得越來越不清楚 –