2

Я использую EF 4.3.1, и я делаю свою первую реализацию Code First и тестирую данные. Вот моя настройка, пытаясь реализовать активную загрузку.Entity Framework 4.3.1 Яркая загрузка нескольких уровней дочерних объектов с помощью фильтра

public class Model 
{ 
    public int Id { get; set; } 
    public ICollection<ModelArchive> ModelArchives { get; set; } 
} 

public class ModelArchive 
{ 
    public int Id { get; set; } 
    public ICollection<Option> Options { get; set; } 
} 

public class Option 
{ 
    public int Id { get; set; } 
    public bool Deleted { get; set; } 
} 

Я хотел бы иметь возможность выбирать только варианты, в которых Deleted == false в моем запросе. До сих пор я опаздываю или это приводит к исключению при запуске запроса.

Вот мой текущий запрос:

using (var db = new ModelContainer()) 
{ 
    db.Configuration.LazyLoadingEnabled = false; 

    var model = db.Models.Where(m => m.Id == 3) 
        .Include(m => m.ModelArchives.Select(o => o.Option).Where(o => o.Deleted == false)); 
} 

Исключение: Message = «В поле Включить выражение пути должны ссылаться на свойства навигации, определенные на типе Используйте пунктирные пути для справки навигационных свойств и Выбора оператора для сбора навигации. свойства. \ r \ nПараметр: путь "

Любая помощь будет оценена по достоинству.

ответ

0

Вы не можете загрузить отфильтрованные данные с помощью платформы Entity Framework. Свойства навигации содержат либо все связанные объекты, либо ни одно из них.

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

0

Вы можете попробовать

using (var db = new ModelContainer()) 
{ 
//db.Configuration.LazyLoadingEnabled = false; 

var model = db.Models.Where(m => m.Id == 3 && m.ModelArchives.Option.Deleted==false) 
       .Include(m => m.ModelArchives.Option); 
} 

Вы можете использовать обобщенную функцию, чтобы получить данные

public List<T> IncludeMultipleWithWhere(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes) 
    { 
     IQueryable<T> itemWithIncludes = dbContext.Set<T>() as IQueryable<T>; 
     try 
     { 
      if (includes != null) 
      { 
       itemWithIncludes = includes.Aggregate(itemWithIncludes, 
          (current, include) => current.Include(include)).Where(predicate); 
      } 

     } 
     catch (Exception ex) 
     { 

     } 
     finally { } 
     return itemWithIncludes.ToList(); 

    } 

ваша функция вызова просто нужно передать параметр как

Expression<Func<Models, bool>> whereCond1 = (m) => m.Id == 3 && m.ModelArchives.Option.Deleted==false; 
Expression<Func<Models, object>>[] includeMulti = { m => m.ModelArchives.Option }; 
0

Вы были правы в отключении lazyloading. Но тогда вы должны отфильтровать свойство навигации в подзапросе, и EF волшебным образом привяжет его к вашему основному запросу. Вот что должно работать

using (var db = new ModelContainer()) 
{ 
    db.Configuration.LazyLoadingEnabled = false; 

    var filteredModelArchives = db.ModelArchives.Select(o => o.Option).Where(o => o.Deleted == false).Include("Options"); 

    var model = db.Models.Where(m => m.Id == 3); 
} 
Смежные вопросы