实体框架快速加载筛选器

问题描述

| 我有一个简单的查询,我想这样做: 1)
Products
ChildProducts
,have2ѭ 2)我想得到所有具有
Category
且具有
ID
为1和
display
= true的
Products
。 3)然后,我想包括所有具有
display
= true的
ChildProducts
。 4)然后包括具有
IsActive
= true的
PriceTiers
。 根据我的阅读,EF不支持带有过滤器的“急切加载”,因此以下操作无效:
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)))
有什么建议么?     

解决方法

从下至上开始,这意味着对
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#中的“ 14”与VB.NET中的“ 15”相同) 执行查询时,最好将
MergeOption
设置为
NoTracking
以外的值。否则,EF将不会确保在查询结果集中多次出现的对象仅实现一次,例如
Product
ChildProduct
: 不需要的结果: PriceTier 1和2具有相同的父级,但是这些父级已实现多次-每个PriceTier一次。 产品1 儿童产品1 PriceTier 1 产品1 儿童产品1 PriceTier 2 理想结果: 将
MergeOption
设置为
NoTracking
以外的任何值,即可得到以下结果: 产品1 儿童产品1 PriceTier 1 PriceTier 2     ,这是一个解决方案,通过使用左联接而不是急切加载,并包括父行(其中过滤器不存在子行),可以使您的\'rows \'匹配您的请求
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};