2010-10-18 3 views
1

У меня есть модель EntityFramework, у которой есть пользовательский объект, который имеет EntityCollection организаций.Как я могу сконденсировать следующий запрос Linq в один IQueryable

Для конкретного пользователя Я пытаюсь написать запрос Linq, чтобы возвращать имена организаций, которые принадлежат пользователю, где этот запрос попадет в db только один раз.

Моя проблема заключается в том, что я не вижу, как написать этот запрос без необходимости материализовать пользователя, а затем запросить коллекцию организации пользователей.

Я хотел бы попытаться написать один запрос, который однажды ударит по db.

То, что я до сих пор:

var orgNames = context.Users 
    .Where(u => u.LoweredUserName == userName.ToLower()) 
    //materialises user 
    .FirstOrDefault() 
    .Organisations 
    //second hit to the db 
    .Select(o => o.Name); 

То, что я был псевдо стремится к, но не может видеть лес за деревьями:

orgNames = context.Users 
    .Where(u => u.LoweredUserName == userName.ToLower()) 
    //don't materialise but leave as IQueryable 
    .Take(1) 
    //The problem: turn what the query sees as possibly multiple 
    // (due to the Take method) EntityCollection<Organisation> into a List<String> 
    .Select(u => u.Organisations.Select(o => o.Name)); 

Я смотрел на агрегатах, но я, кажется, идет в кругах :)

ответ

2

Doh! Я думаю, что я могу ответить на свой вопрос с помощью SelectMany конденсировать Коллекция коллекций в одну коллекции так:

orgNames = context.Users.Where(u => u.LoweredUserName == userName.ToLower()) 
       .Take(1) 
       .SelectMany(u => u.Organisations) 
       .Select(o => o.Name); 
0

Я предполагаю, что Пониженное имя пользователя является уникальным, в противном случае запрос будет довольно бессмысленным, так вы можете просто использовать.

context.Users 
     .Where(u => u.LoweredUserName == userName.ToLower()) 
     .Select(u => u.Organisations.Select(o => o.Name)); 
Смежные вопросы