2016-06-09 62 views
5

Ho un oggetto che ha una lista di lunghezza variabile di elementi (listaIncoming nell'esempio di codice) e un elenco di persone che hanno ciascuna un elenco di elementi. Voglio restituire solo quelle persone che hanno tutti gli elementi nella lista in entrata.Linq restituisce gli oggetti padre che hanno elementi figlio che corrispondono a TUTTI gli elementi nell'elenco separato

Quindi, guardando l'esempio, voglio solo la persona 1 e 3 restituiti.

Le persone si trovano in un database e voglio recuperare il minor numero possibile di dati, quindi sto cercando di capire quale deve essere la query di linq per raggiungere questo obiettivo? Se sapessi che la lunghezza della lista entrante sarà sempre la stessa che potrei fare "... Qualsiasi (..) & & ... Qualsiasi (...) & &" ecc. - ma la lunghezza può variare.

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

risposta

2

Ciò restituisce tutte le persone che hanno tutti gli elementi di incomingList nella loro 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 }))); 

tipi anonimi dovrebbero avere gli oggetti con nomi uguali e tipi di risolvere a "uguali", che condizione è soddisfatta in questo caso.

+0

Grazie, funziona ma non riesco a capire perché è quando non fa riferimento a entrambe le proprietà, cosa mi manca? – crockels

+0

No, dovrebbe corrispondere su ItemValue e ItemType, piuttosto che su ItemValue. (Che cosa sembra fare la tua soluzione, ma non riesco a vedere come!) – crockels

+0

Mentre questo funziona sull'esempio non funziona quando viene spostato sul mio codice principale. Ottengo un errore EF: impossibile creare un valore costante di tipo 'DTO.MatchListIten'. In questo contesto sono supportati solo tipi primitivi o tipi di enumerazione. DTO.MatchListItem non è un'entità database, Person e Item sono. – crockels