2016-06-09 20 views
5

Mam obiekt, który ma listę elementów o zmiennej długości (lista przychodzących w przykładowym kodzie) i listę osób, z których każda ma listę elementów. Chcę zwrócić tylko te osoby, które mają wszystkie pozycje w liście przychodzącej.Zwróć obiekty nadrzędne Linq, które mają elementy podrzędne pasujące do WSZYSTKICH pozycji na oddzielnej liście.

Patrząc na przykład, chcę tylko, aby osoba 1 i 3 wróciła.

Ludzie są w bazie danych i chcę pobrać tak mało danych, jak to możliwe, więc staram się dowiedzieć, jakie kwerendy linq musi być, aby to osiągnąć? Gdybym wiedział, że długość listy przychodzącej zawsze będzie taka sama, mogę zrobić "... Dowolny (..) & & ... Dowolny (...) & &" itd. - ale długość będzie się różnić.

void Main() 
{ 
    var incomingList = new IncomingItem(); 

    var matchItem1 = new MatchItem { ItemType = "objectId", ItemValue = "60" }; 
    var matchItem2 = new MatchItem { ItemType = "area", ItemValue = "CU" }; 

    incomingList.MatchList = new List<MatchItem>(); 
    incomingList.MatchList.Add(matchItem1); 
    incomingList.MatchList.Add(matchItem2); 

    var people = new List<Person>(); 

    var person1 = new Person { Id = 1 }; 
    person1.ListOfItems = new List<Item>(); 
    person1.ListOfItems.Add(new Item { ItemType = "objectId", ItemValue = "60" }); 
    person1.ListOfItems.Add(new Item { ItemType = "objectId", ItemValue = "1" }); 
    person1.ListOfItems.Add(new Item { ItemType = "objectId", ItemValue = "30" }); 
    person1.ListOfItems.Add(new Item { ItemType = "area", ItemValue = "CO" }); 
    person1.ListOfItems.Add(new Item { ItemType = "area", ItemValue = "CU" }); 
    people.Add(person1); 

    var person2 = new Person { Id = 2 }; 
    person2.ListOfItems = new List<Item>(); 
    person2.ListOfItems.Add(new Item { ItemType = "objectId", ItemValue = "60" }); 
    people.Add(person2); 

    var person3 = new Person { Id = 3 }; 
    person3.ListOfItems = new List<Item>(); 
    person3.ListOfItems.Add(new Item { ItemType = "objectId", ItemValue = "60" }); 
    person3.ListOfItems.Add(new Item { ItemType = "area", ItemValue = "CU" }); 
    people.Add(person3); 

    var person4 = new Person { Id = 4 }; 
    person4.ListOfItems = new List<Item>(); 
    person4.ListOfItems.Add(new Item { ItemType = "objectId", ItemValue = "12" }); 
    people.Add(person4); 
} 

public class IncomingItem 
{ 
    public IList<MatchItem> MatchList { get; set; } 
} 

public class MatchItem 
{ 
    public List<object> SomeMoreInformation { get; set; } 

    public string ItemType { get; set; } 

    public string ItemValue { get; set; } 
} 

public class Person 
{ 
    public int Id { get; set; } 

    public IList<Item> ListOfItems { get; set; } 
} 

public class Item 
{ 
    public int Id { get; set; } 

    public int PersonId { get; set; } 

    public string ItemType { get; set; } 

    public string ItemValue { get; set; } 
} 

Odpowiedz

2

ta zwraca wszystkie osoby, które posiadają wszystkie elementy incomingList w ich ListOfItems:

var result = people.Where(p => incomingList.MatchList 
         .All(l => p.ListOfItems.Select(loi => new { loi.ItemType, loi.ItemValue }) 
          .Contains(new { l.ItemType, l.ItemValue }))); 

typy anonimowych powinien posiadać właściwości z jednakowych nazwach i typach rozwiązać na „równe”, stan, który jest spełniony w ta sprawa.

+0

Dziękuję, to działa, ale nie mogę zrozumieć, dlaczego tak jest, gdy nie odnosi się do obu właściwości, czego mi brakuje? – crockels

+0

Nie, powinno pasować zarówno do ItemValue, jak i ItemType, a nie tylko do ItemValue. (Wydaje się, że twoje rozwiązanie działa, ale nie widzę jak!) – crockels

+0

Chociaż działa to na przykładzie, nie działa po przeniesieniu do mojego głównego kodu. Wystąpił błąd EF: Nie można utworzyć stałej wartości typu "DTO.MatchListIten". W tym kontekście obsługiwane są tylko typy pierwotne lub typy wyliczeniowe. DTO.MatchListItem nie jest jednostką bazy danych, osobą i przedmiotem. – crockels