2011-08-25 16 views
5

dụ đầu tiên mà hoạt động:LINQ và Có

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)); 

Bây giờ tôi muốn sử dụng hai danh sách các đối tượng như là một nguồn và nhận được danh sách các đối tượng có giá trị này tương tự cho ID thành viên.

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

Dưới đây không biên dịch:

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

Tôi biết điều đó là sai nhưng đặt nó vào đây để hiểu rõ hơn. tôi sẽ đánh giá cao một người nào đó chỉ cho tôi con đường đúng đắn :-)

Trân Mariusz

+1

Cảm ơn bạn MDM để chỉnh sửa :-) – Mariusz

+0

Nếu chỉ tất cả các chỉnh sửa đã được bắt đầu – Baz1nga

Trả lời

3

Bạn có thể làm cho class Test của bạn equatable:

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

Sau đó, điều này sẽ làm việc:

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

Tôi thích câu trả lời này nhất bởi vì biểu thức lambda vẫn trông sạch sẽ và dễ đọc. Cảm ơn bạn rất nhiều :) – Mariusz

2

enter code here phiên bản đơn giản sẽ là

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

hoặc bạn có thể sử dụng phiên bản LINQ của một bên tham gia nếu bạn không có sự lặp lại

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

hoặc bạn có thể sử dụng 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()); 

cuối cùng nếu bạn ghi đè Equals và GetHashCode() trong bài kiểm tra bạn có thể làm cho họ có thể so sánh

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(); 
} 

lần nữa điều này sẽ cho phép bạn làm list1.Intersect(list2) hoặc list2.Intersect(list1)

+0

var query = List2 .Where (c => list1.Select (l => l.ID) .Contains (c.ID)) trông khá dễ đọc cũng như tham gia bằng cách sử dụng lambdas chỉ đơn giản là làm cho tôi khóc :-) Cảm ơn rất nhiều Bob! – Mariusz

6

Bạn có thể thực hiện một inner join như sau:

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

hoặc

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

+1, cách tiếp cận tốt hơn nhiều. – mdm

+0

Cảm ơn. Làm việc như một say mê. Tôi quên rằng tham gia sẽ lọc ra ID chỉ ở bên trái hoặc bên phải. Đi về phía trước (chúng tôi có giao lộ tại thời điểm này) bạn sẽ nhận được thông tin như thế nào. Ngoại trừ? – Mariusz

+0

@aristo có một cái nhìn vào phiên bản cuối cùng trên câu trả lời của tôi, bạn chỉ có thể thay thế các đường giao nhau với một dòng trừ –

2

Hãy thử

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

Bạn cần phải liệt kê các bộ sưu tập khác với mã của riêng bạn để có được những gì bạn muốn, bởi vì Chứa sử dụng Equals chức năng, trong đó cho các đối tượng sẽ chỉ phù hợp với các tài liệu tham khảo .

+0

Ví dụ rất đẹp và rõ ràng. Cảm ơn Michael! Tôi không biết rằng có rất nhiều cách để đạt được điều đó :-) – Mariusz