2012-05-25 92 views
1

這看起來相當簡單,但我無法專注。
比方說,我有這樣的定義2類:使用LINQ從兩個IEnumerables中選擇

class Class1 
{ 
    public int Document; 
    public decimal Amount; 
} 

class Class2 
{ 
    public string Document; 
    public decimal Amount; 
} 

IEnumerable<Class1> result1IEnumerable<Class2> result2定義和填充數據。

我有這樣限定的第三類:

class ResultClass 
{ 
    public string Document; 
    public decimal? AmountFromClass1; 
    public decimal? AmountFromClass2; 
} 

我想LINQ查詢,其選擇從該第一結果的某些字段和從所述第二結果的某些字段,並把它們在定義爲List<ResultClass> result第三結果。
例如,如果我有第一結果(result1)填充這樣的:

Document Amount 
    1   1.55 
    2   2.55 

和第二結果(result2)填充這樣的:

Document Amount 
    "d-1"  1.22 
    "d-2"  2.22 

我想有最終result (秩序無關緊要):

Document AmountFromClass1 AmountFromClass2 
    "1"    1.55    null 
    "d-1"   null    1.22 
    "2"    2.55    null 
    "d-2"   null    2.22 

目前我做這種使用兩個foreach語句,就像這樣:

List<ResultClass> result = new List<ResultClass>(); 

foreach (var o in result1) 
    result.Add(new ResultClass 
    { 
     Document = o.Document.ToString(), 
     AmountFromClass1 = o.Amount, 
     AmountFromClass2 = null 
    }); 

foreach (var o in result2) 
    result.Add(new ResultClass 
    { 
     Document = o.Document, 
     AmountFromClass1 = null, 
     AmountFromClass2 = o.Amount 
    }); 

但我想做到這一點使用LINQ。
可能嗎?

編輯:細化問題(還增加了實體框架標籤)
由於這僅僅是一個代碼示例,我知道有可能是在一個單一的LINQ這樣做沒有實際利益聲明,因爲它會做同樣的事情。
不過,我正在尋找一個性能的改進,其中result1result2實際上是從LINQ到實體IQueryables,在某種程度上,所以我可以做這樣的事情:

List<ResultClass> MyFunc() 
{ 
    Database DB = new Database(); // object context 
    var result1 = DB.Class1s.Where(...); 
    var result2 = DB.Class2s.Where(...); 
    return SomeMagic() 
     .Select(x => new ResultFunc { ... }) 
     .ToList(); 
} 
+2

正如在答案中所看到的那樣,您絕對可以在LINQ中做到這一點,但它幾乎完全相同的代碼量,幾乎完全可以高效地執行。我不想費心去改變它,這樣就好了。也就是說,我會在代碼中添加一些額外的空白,而不是試圖在一個文本行上做一些事情;它只是更難以閱讀。 – Servy

+0

@Servy良好的評論,我確實提出了新的觀點,並且傾向於閱讀更易於閱讀的代碼,但是當我輸入這個內容時我很匆忙,所以難怪它看起來像這樣。我正在編輯它。 –

回答

4

項目每個項目都集合到一個ResultClass對象和將兩者連接起來得到的可枚舉:

var query1 = from o in result1 
      select new ResultClass 
      { 
       Document = o.Document.ToString(), 
       AmountFromClass1 = o.Amount 
      }; 

var query2 = from o in result2 
      select new ResultClass 
      { 
       Document = o.Document, 
       AmountFromClass2 = o.Amount 
      }; 

var result = query1.Concat(query2).ToList(); 
+0

如果result1和result2是從linq到實體的IQueryables,那麼這個查詢是否會在'select'或僅在'ToList()'上執行? –

1

這是您的代碼轉換成LINQ

var result = result1 
    .Select(c => new ResultClass() { Document = c.Document.ToString(), AmountFromClass1 = c.Amount }) 
    .Concat(result2.Select(c => new ResultClass() { Document = c.Document, AmountFromClass2 = c.Amount })) 
    .ToList(); 
0

根據需要輸出,似乎如果你想交叉連接,那麼你可以使用查詢語法與條款多像你需要一個聯盟

 var class1 = new List<Class1>(); 
     var class2 = new List<Class2>(); 
     class1.Add(new Class1(){Document=1, Amount = 1.0M}); 
     class1.Add(new Class1(){Document=2, Amount = 1.0M}); 
     class2.Add(new Class2(){Document="1", Amount = 1.0M}); 
     class2.Add(new Class2(){Document="3", Amount = 1.0M}); 
      var result = class1.Select(x=> new ResultClass{Document = x.Document.ToString(), AmountFromClass1=x.Amount, AmountFromClass2 = null}).Union(
          class2.Select(x=> new ResultClass{Document = x.Document, AmountFromClass2=x.Amount, AmountFromClass1 = null}) ); 

Example