2011-01-18 15 views
10

Mam podmioty Group i User.
Obiekt Group ma właściwość Users, która jest listą użytkowników.
Użytkownik ma właściwość o nazwie IsEnabled.Linq To Entities - jak filtrować jednostki podrzędne

Chcę napisać zapytanie linq, które zwraca listę Group s, która składa się tylko z User s, której IsEnabled jest prawdziwa.

tak na przykład, dla danych, jak poniżej
AllGroups
grupy A
użytkownika 1 (IsEnabled = prawda)
użytkownika 2 (IsEnabled = prawda)
Użytkownik 3 (IsEnabled = fałsz)

Grupa B
obsługi 4 (IsEnabled = prawda)
użytkownika 5 (IsEnabled = fałsz)
użytkownika 6 (IsEnabled = false)

Chcę dostać
FilteredGroups
Grupa A
User 1 (IsEnabled = true)
User 2 (IsEnabled = true)

Grupa B
Użytkownik 4 (IsEnabled = true)

Próbowałem następującą kwerendę, ale Visual Studio mówi mi, że
[nie można przypisać własność lub Indexer „użytkownicy” to - to jest tylko do odczytu]

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

dziękuję za pomoc!

+0

używasz EF4? Jeśli tak, czy korzystasz z POCO? W jaki sposób zadeklarowano "Group.Users"? – RPM1984

+2

Możesz to łatwo osiągnąć dzięki filtrowanemu Uwzględnieniu. Głosuj na funkcję [tutaj] (https://entityframework.codeplex.com/workitem/47)! – Chris

Odpowiedz

8

udało mi się to zrobić poprzez przekręcenie zapytanie do góry nogami:

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

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

Używając ToList() wymusić udostępnia go do bazy danych, które są wymagane, ponieważ w przeciwnym razie wykonanie odroczony jest w drodze. Druga kwerenda ponownie zamawia pobrane dane.

Uwaga: Może się zdarzyć, że nie będziesz w stanie udtupować swoich jednostek!

+0

możesz mi pomóc w tym zapytaniu linq: http: //stackoverflow.com/questions/38120664/how-to-group-by-on-2-child-entities-and-get-total-of-both-this- dzieci-byty –

9

Nie ma „miły” sposób to zrobić, ale można spróbować tego - projekt zarówno Group i filtrowane Users na anonimowego obiektu, a następnie Select tylko Groups:

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

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

Ten ISN” t udokumentowana funkcja i ma związek ze sposobem, w jaki EF tworzy kwerendy SQL - w takim przypadku powinien odfiltrować kolekcję podrzędną, aby Twoja lista FilteredGroups zawierała tylko aktywnych użytkowników.

Jeśli to działa, można spróbować łączenia kodu:

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

(jest niesprawdzone, a wynik zależy od tego jak EF będzie przetwarzał drugi Select, więc byłoby miło, jeśli pozwolisz nam znać, który metoda działa po wypróbowaniu tego).

1

spróbować coś takiego i wciąż masz swoje podmioty:

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

ten sposób powinny nadal mieć możliwość korzystania z Group.Users

0

Jeśli chcesz zachować swoją strukturę jednostki, spróbuj tego :

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) 
    { 
    } 
} 

I z pewnością możesz modyfikować swoje istoty!

Powiązane problemy