实体框架4.3.1渴望使用过滤器加载多个子对象级别

时间:2013-08-05 15:02:11

标签: entity-framework ef-code-first parent-child eager-loading

我正在使用EF 4.3.1,我正在第一次实现Code First并测试数据。这是我尝试实施预先加载的设置。

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 =“Include路径表达式必须引用在类型上定义的导航属性。使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性。\ r \ nParameter name:path”

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:0)

您无法使用Entity Framework加载过滤后的数据。导航属性包含所有相关实体,或者不包含任何相关实体。

考虑手动连接并返回未删除选项的匿名对象。

答案 1 :(得分: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 };

答案 2 :(得分:0)

你在禁用延迟加载方面是正确的。 但是,您必须在子查询中过滤导航属性,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);
}