2011-08-25 87 views
5

其中工程第一個例子:LINQ和包含

public class Test 
{ 
    public int ID; 
    public string Name; 
} 

List<int> list1 = Load1(); 
List<Test> list2 = Load2(); 

var query = list2.Where(c => list1.Contains(c.ID)); 

現在我想用對象的兩個列表作爲源,並得到有會員ID此相同的值對象列表。

List<Test> list1 = Load2(); 
List<Test> list2 = Load2(); 

以下不會編譯:

var query = list2.Where(c => **list1.ID.Contains**(c.ID)); 

我知道這是錯誤的,但放在這裏更好的理解。 我希望有人告訴我:-)

問候 正道的Mariusz

+1

謝謝您對MDM編輯:-) – Mariusz

+0

如果只有所有的編輯都感謝 – Baz1nga

回答

3

你可以讓你的測試類equatable:

public class Test : IEquatable<Test> 
{ 
    public int Id {get;set;} 
    public bool Equals(Test other) 
    { 
    return this.Id == other.Id; 
    } 
} 

那麼這會工作:

list1.Where(item => list2.Contains(item)); 
+0

我最喜歡這個答案,因爲lambda表達式仍然看起來乾淨和可讀。 非常感謝:) – Mariusz

2

enter code here簡單的版本將是

var query = list2.Where(c=> list1.Select(l=>l.ID).Contains(c.ID)) 

,或者你可以使用一個內部的LINQ版本,如果你加入沒有重複

var query = list2.Join(list1,a=>a.ID,b=>b.ID,(a,b)=>a); 

或者你可以使用System.Collections.Generic.IEQualityComparer

public class TestComparerer : IEqualityComparer<Test> { 
    bool IEqualityComparer<Test>.Equals(Test a, Test b) { 
     return a!=null && b!=null && a.ID.Equals(b.ID); 
    } 

    int IEqualityComparer<Test>.GetHashCode(Test a){ 
    return a.ID.GetHashCode(); 
    } 
} 

var query = list2.intersect(list1,new TestComparer()); 

最後,如果你凌駕於測試Equals和GetHashCode()方法,你可以讓他們媲美

public override bool Equals(object o) { 
var other=o as Test; 
return other!=null && this.ID==other.ID; 
} 

public override int GetHashCode() { 
return ID.GetHashCode(); 
} 

再次,這將允許你這樣做list1.Intersect(list2)list2.Intersect(list1)

+0

VAR的查詢=列表2 .Where(c => list1.Select(l => l.ID).Contains(c.ID))看起來很可讀,使用lambda表達式的聯接只是讓我哭泣:-)非常感謝Bob! – Mariusz

6

您可以執行inner join作爲如下:

var query = from x in list1 
      join y in list2 on x.ID equals y.ID 
      select new { x, y }; 

var query = list1.Join(list2, 
         x => x.ID, 
         y => y.ID, 
         (x, y) => new { x, y }); 
+2

+1,更好的方法。 – mdm

+0

謝謝。奇蹟般有效。我忘記了這個連接只會過濾掉左側或右側的ID。 向前走(我們現在有一個交叉點),你會如何得到像.Except? – Mariusz

+0

@aristo看看我的答案的最後一個版本,你可以用一條線代替相交線 –

2

嘗試

list2.Where(c => list1.Any(d => d.ID == c.ID)); 

你需要用自己的代碼來枚舉其他集合得到你想要的東西,因爲。載使用.Equals功能,這對於對象將只匹配與參考。

+0

非常好,乾淨的例子。謝謝邁克爾!我不知道有這麼多的方法實現:-) – Mariusz