实体框架渴望加载过滤器

时间:2011-04-14 06:16:02

标签: entity-framework eager-loading

我想做一个简单的查询:

1)Products ChildProducts PriceTiersProducts 2)我希望得到Category ID Display为1且ChildProducts =真的所有Display。 3)然后我想要包含PriceTiers = true的所有IsActive 4)然后包含ProductRepository.Query.IncludeCollection(Function(x) x.ChildProducts.Where(Function(y) y.Display).Select(Function(z) z.PriceTiers.Where(Function(q) q.IsActive))).Where(Function(x) x.Categories.Any(Function(y) y.ID = ID))) = true。{/ p>的{{1}}

根据我的阅读,EF不支持使用过滤器进行预先加载,因此以下内容不起作用:

{{1}}

有什么建议吗?

2 个答案:

答案 0 :(得分:9)

从下往上开始,意思是,在PriceTier对象及其父项上应用过滤器,并包含其父项(C#抱歉,但希望您明白这一点):

repository.PriceTiers
  .Include("ChildProduct.Product") // eager load parents
  .Where(priceTier => 
    priceTier.IsActive &&
    priceTier.ChildProduct.Display &&
    priceTier.ChildProduct.Product.ID == 1 &&
    priceTier.ChildProduct.Product.Display)
  .AsEnumerable() // execute SQL statement
  .Select(priceTier => 
    priceTier.ChildProduct.Product) // return products rather than price tiers

(注意:C#中的priceTier =>与VB.NET中的Function(priceTier)相同)

理想情况下,

MergeOption在执行查询时应设置为其他而不是NoTracking。否则,EF将无法确保在查询结果集中多次出现的对象仅实现一次,例如ProductChildProduct

不需要的结果: PriceTier 1和2具有相同的父母,但父母已多次实现 - 每个PriceTier一次。

  • 产品1
    • ChildProduct 1
      • PriceTier 1
  • 产品1
    • ChildProduct 1
      • PriceTier 2

理想的结果:MergeOption设置为NoTracking以外的任何内容即可获得以下结果:

  • 产品1
    • ChildProduct 1
      • PriceTier 1
      • PriceTier 2

答案 1 :(得分:0)

这是一个解决方案,可以提供您的行'通过使用左连接而不是预先加载来匹配您的请求,并包括过滤器不存在子行的父行

var query = from product in Products
                join child_ in ChildProducts on product equals child_.Product into child_join
                from child in child_join.DefaultIfEmpty()
                join tier_ in PriceTiers on child equals tier_.ChildProduct into tier_join
                from tier in tier_join.DefaultIfEmpty()
                where product.Display && product.Category.ID == 1
                where child == null || child.Display
                where tier == null || tier.IsActive
                select new {product, child, tier};