2016-02-01 2 views
3

Текущая настройка EF в моем приложении - это ленивая загрузка, что отлично по большей части. Тем не менее, я потерял попытку выяснить, как загрузить список связанных объектов на основе их атрибута бит IsEnabled.Entity Framework поддерживает загрузку по определенному атрибуту

В этом примере я просто возвращаю список сущностей.

return Context.Entities.ToList() 

Скажем Entities объект содержит список ChildEntities так:

public class Entities 
{   
    private string EntityName; 

    private List<ChildEntities> ChildEntities; 
} 

public class ChildEntites 
{   
    private string ChildEntityName; 
    private bool IsEnabled; 
} 

Я хочу только хочу, чтобы выйти из ChildEntities на основе их IsEnabled флага при загрузке списка Entities.

+0

Я не думаю, что это возможно, используя 'Include()' для активной загрузки, но, возможно, ленивый загруженный 'Context.Entities.Where (e => e.IsEnabled) .ToList()' достаточно быстро? Это должно выполняться в БД до того, как будут реализованы какие-либо объекты. –

+1

Нельзя использовать активную загрузку (Включить), поскольку она не поддерживает фильтрацию, Include всегда загружает всю коллекцию –

ответ

1

Пара способов я бы рекомендовал этот подход. Я бы либо ленивый груз, где IsEnabled = false и нетерпеливая загрузка в отдельном вызове, где IsEnabled = true ИЛИ, когда у вас есть ленивая загруженная коллекция, в отдельном вызове получайте дочерние объекты, где IsEnabled = true. Я не верю, что вы сможете сделать это одним звонком. Другой вариант будет хранимой процедурой. Надеюсь, это поможет.

2

Вы можете использовать метод Include() для загрузки всех дочерних объектов, а затем выбрать только те, которые включены как

Context.Entities.Include("ChildEntites").Select(c => e.IsEnabled == true) 

Другой способ получить объекты фильтра, а затем выполнить запрос, как показано in this post

var data = from e in Context.Entities 
      select new 
      { 
       Entities = e, 
       Childs = e.ChildEntites.Where(c => c.IsEnabled == true) 
      }; 

var Results = data.ToArray().Select(x => x.Entities); 
1

Используя проекцию

var entities = context.Entities 
         .Select(x => new {x, x.ChildEntities.Where(y => y.IsEnabled)) 
         .ToList() // resolve from database before selecting the main entity 
         .Select(x => x.x); 

Использование сторонней библиотеки

EF + Query IncludeFilter позволяют легко фильтровать связанные объекты

var entities = context.Entities.IncludeFilter(x => x.ChildEntities.Where(y => y.IsEnabled)) 
           .ToList(); 

Вы можете найти документацию here

Отказ от ответственности: Я владелец проекта EF+.

2

Я думаю, что при загрузке связанных объектов в случае, если вы используете ленивую загрузку или загрузку, вы не можете фильтровать, если вы не спроецируете свой запрос на анонимный тип или DTO, но если у вас есть экземпляр объекта, вы можете загрузить связанные объекты, основанные на состоянии с использованием явной загрузки:

var entity=context.Entities.FirstOrDefault(); 
context.Entry(entity) 
     .Collection(b => b.ChildEntities) 
     .Query() 
     .Where(ce => ce.IsEnabled == true) 
     .Load(); 

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

var query= from e in Context.Entities.Include(c=>c.ChildEntities) 
      select new EntityDTO 
      { 
       EntityName= e.EntityName, 
       ChildEntites= e.ChildEntites.Where(c => c.IsEnabled == true) 
      }; 
1

У меня была аналогичная проблема. Я решил это следующим образом.

Создайте новый метод в своих объектах.Давайте называть это ChildEntitiesEnabled

public ICollection<ChildEntity> ChildEntitiesEnabled() 
{ 
     //First I get the full list using the lazy loading... 
     var allChildEntities=ChildEntities.ToList(); 

     //do further processing if there is data 
     if(allChildEntities!=null && allChildEntities.Count()>0) 
     { 

     var childEntitiesEnabled = ChildEntities.Where(x=>x.Enabled==true).ToList(); 

     return childEntitiesEnabled; 
     } 

     return null; //or you can return an empty list... 
} 

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

Смежные вопросы