Linq и Содержит - PullRequest
       19

Linq и Содержит

5 голосов
/ 26 августа 2011

Первый пример, который работает:

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

Теперь я хотел бы использовать два списка объектов в качестве источника и получить список объектов, которые имеют такие же значения для идентификатора члена.

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

Ниже не компилируется:

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

Я знаю, что это неправильно, но поместил это здесь для лучшего понимания.Я был бы признателен, если бы кто-то показал мне правильный путь: -)

С уважением, Мариуш

Ответы [ 4 ]

6 голосов
/ 26 августа 2011

Вы можете выполнить внутреннее соединение следующим образом:

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 });
3 голосов
/ 26 августа 2011

Вы можете сделать свой тестовый класс равным:

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));
2 голосов
/ 26 августа 2011

Попробуйте

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

Вам нужно перечислить другую коллекцию с вашим собственным кодом, чтобы получить то, что вы хотите, потому что .Contains использует функцию .Equals, которая для объектов будет просто сопоставляться со ссылкой.

2 голосов
/ 26 августа 2011

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

или вы можете использовать Систему.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)

...