Linq Запрос активных дочерних объектов - PullRequest
2 голосов
/ 16 декабря 2011

Я не знал, что написать в заголовке вопроса.Вот мой образец.У меня есть класс Foo, который имеет коллекцию Bars следующим образом:

public class Foo  
{  
    public bool Active {get; set;}  
    public ICollection<Bar> Bars {get; set;}  
}  

public class Bar
{
    public bool Active {get; set;}
}

Как вы можете видеть, Foos и Bars можно установить как неактивные (Active = false).Мне нужно написать сервис (RIA), который будет возвращать каждый активный Foo с его активными барами.
Итак, это то, что у меня есть:

public IQueryable<Foo> GetFoos()
{
    return ObjectContext.Foos.Where(f => f.Active)
                             .Include("Bars");
}

Дело в том, что приведенный выше запрос возвращает каждыйactive Foo с каждым Bar, так как мне включить only active Bars?

Ответы [ 2 ]

1 голос
/ 05 января 2012

Метод Include является частью LazyLoading.Ленивая загрузка - это все или ничего, поэтому вы не можете сказать EF загружать только несколько баров.

Однако вы можете попытаться использовать анонимный объект в результате:

context.Foos
.Where(f => f.Active)
.Select(f => new { Foo = f, Bars = f.Bars.Where(b => b.IsActive }); 
1 голос
/ 05 января 2012

EF не делает это легким, потому что идет вразрез с философией того, как EF предназначен для работы.Если бы было легко написать этот запрос так, чтобы коллекция Bars каждой сущности Foo содержала только «активные» сущности Bar, то каждая сущность Foo не была бы точной моделью состояния базы данных.

С другой стороны, если вы пишете запрос с использованием проекции (вместо непосредственного извлечения сущностей Foo), вы получаете большую гибкость.Например, вы могли бы написать запрос следующим образом:

var query =
    from f in ObjectContext.Foos
    where f.Active
    select new { Foo = f, ActiveBars = f.Bars.Where(b=>b.Active)}

В этот момент вы могли бы написать цикл foreach, чтобы заново связать активные Bar сущности с каждым Fooentity:

var results = query.ToList();

foreach (var r in results)
    r.Foo.Bars = r.ActiveBars;

И, наконец, выполнить запрос LINQ локально, чтобы получить результаты:

return (from r in results select r.Foo).ToList();

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

...