Linq To Entities: come filtrare su quadro figlio

Ho quadro Group e User .
l’ quadro di Group ha una proprietà Users che è un elenco di utenti.
L’utente ha una proprietà denominata IsEnabled .

Voglio scrivere una query linq che restituisce un elenco di Group , che consiste solo di User i cui IsEnabled è true.

quindi ad esempio per dati come sotto
AllGroups
Gruppo A
Utente 1 (IsEnabled = true)
Utente 2 (IsEnabled = true)
Utente 3 (IsEnabled = false)

Gruppo B
Utente 4 (IsEnabled = true)
Utente 5 (IsEnabled = false)
Utente 6 (IsEnabled = false)

voglio ottenere
FilteredGroups
Gruppo A
Utente 1 (IsEnabled = true)
Utente 2 (IsEnabled = true)

Gruppo B
Utente 4 (IsEnabled = true)

Ho provato la seguente query, ma Visual Studio me lo dice
[Proprietà o indicizzatore ‘Utenti’ non possono essere assegnati a – è di sola lettura]

 FilteredGroups = AllGroups.Select(g => new Group() { ID = g.ID, Name = g.Name, ... Users = g.Users.Where(u => u.IsInactive == false) }); 

grazie per l’aiuto!

Sono riuscito a farlo capovolgendo la query:

 var users = (from user in Users.Include("Group") where user.IsEnabled select user).ToList().AsQueryable() from (user in users select user.Group).Distinct() 

Usando il ToList () si forza un roundtrip al database che è richiesto perché altrimenti l’esecuzione differita si intromette. La seconda query riordina solo i dati recuperati.

Nota: potresti non essere in grado di udire successivamente le tue quadro!

Non c’è un modo “bello” per farlo, ma puoi provare questo: proietta sia gli Users Group che quelli filtrati su un object anonimo, quindi Select solo i Groups :

 var resultObjectList = AllGroups. Select(g => new { GroupItem = g, UserItems = g.Users.Where(u => !u.IsInactive) }).ToList(); FilteredGroups = resultObjectList.Select(i => i.GroupItem).ToList(); 

Questa non è una funzionalità documentata e ha a che fare con il modo in cui EF costruisce le query SQL: in questo caso dovrebbe filtrare la raccolta FilteredGroups , quindi l’elenco di FilteredGroups conterrà solo utenti attivi.

Se funziona, puoi provare a unire il codice:

 FilteredGroups = AllGroups. Select(g => new { GroupItem = g, UserItems = g.Users.Where(u => !u.IsInactive) }). Select(r => r.GroupItem). ToList(); 

(Questo non è stato verificato e il risultato dipende da come EF elaborerà il secondo Select , quindi sarebbe bello se ci faccia sapere quale metodo funziona dopo averlo provato).

prova qualcosa di simile e avrai ancora le tue quadro:

 FilteredGroups = AllGroups.Select(g => new { Group = g, Users = g.Users.Where(u => u.IsInactive == false) }).AsEnumerable().Select(i => i.Group); 

In questo modo dovresti comunque essere in grado di utilizzare Group.Users

Se vuoi mantenere la tua struttura di quadro, prova questo:

 var userGroups = context.Users.Where(u => !u.IsInactive).GroupBy(u => u.Group); foreach (var userGroup in userGroups) { // Do group stuff, eg: foreach (var user in userGroup) { } } 

E certamente puoi modificare le tue entity framework!