2011-01-18 11 views
10

Tengo entidades Group y User.
entidad Group tiene Users propiedad que es una lista de usuarios.
El usuario tiene una propiedad llamada IsEnabled.Linq To Entities - cómo filtrar entidades hijo

Quiero escribir una consulta de linq que devuelve una lista de Group s, que solo consta de User s cuya IsEnabled es verdadera.

así por ejemplo, para los datos, como a continuación
AllGroups
Grupo A
usuario 1 (IsEnabled = true)
usuario 2 (IsEnabled = true)
usuario 3 (IsEnabled = false)

Grupo B
usuario 4 (IsEnabled = true)
usuario 5 (IsEnabled = false)
Usuario 6 (IsEnabled = false)

quiero conseguir
FilteredGroups
Grupo A
usuario 1 (IsEnabled = true)
usuario 2 (IsEnabled = true)

Grupo B
Usuario 4 (IsEnabled = verdadero)

Probé la siguiente consulta, pero Visual Studio me dice que
[no se pueden asignar propiedad o indizador de los usuarios a - que es de sólo lectura]

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

gracias por su ayuda!

+0

¿estás usando EF4? Si es así, ¿está usando POCO? ¿Cómo se declara 'Group.Users'? – RPM1984

+2

Puede lograr esto fácilmente con Include filtrado. ¡Vote por la característica [aquí] (https://entityframework.codeplex.com/workitem/47)! – Chris

Respuesta

8

me las arreglé para hacerlo activando la consulta al revés:

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

from (user in users 
     select user.Group).Distinct() 

Al utilizar el ToList() fuerza un ida y vuelta a la base de datos que se requiere, porque de lo contrario la ejecución diferida viene en camino. La segunda consulta solo reordena los datos recuperados.

Nota: ¡Es posible que no pueda udpatear sus entidades después!

+0

me pueden ayudar con esta consulta linq: http: //stackoverflow.com/questions/38120664/how-to-group-by-on-2-child-entities-and-get-total-of-both-this- entidades infantiles –

9

No hay manera "agradable" de hacer esto, pero usted podría probar este - proyecto tanto, Group y se filtra Users sobre un objeto anónimo y, a continuación, Select sólo el Groups:

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

FilteredGroups = resultObjectList.Select(i => i.GroupItem).ToList(); 

Esto no es Es una característica documentada y tiene que ver con la forma en que EF construye consultas SQL; en este caso, debe filtrar la colección hija, por lo que su lista FilteredGroups solo contendrá usuarios activos.

Si esto funciona, puede intentar fusionar el código:

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

(Esto no se ha probado y el resultado depende de cómo EF procesará la segunda Select, por lo que sería bueno si usted nos deja saber lo que el método funciona después de haberlo probado).

1

intentar algo como esto y usted todavía tiene sus entidades:

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

De esa manera usted aún debe ser capaz de utilizar Group.Users

0

Si desea conservar la estructura de su entidad, intente esto :

var userGroups = context.Users.Where(u => !u.IsInactive).GroupBy(u => u.Group); 

foreach (var userGroup in userGroups) 
{ 
    // Do group stuff, e.g.: 
    foreach (var user in userGroup) 
    { 
    } 
} 

¡Y ciertamente puede modificar sus entidades!

Cuestiones relacionadas