实体框架4:使用自我跟踪实体的过滤器进行预先加载(包括)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实体框架4:使用自我跟踪实体的过滤器进行预先加载(包括)相关的知识,希望对你有一定的参考价值。

我有一个解决方案,我使用RTM模板创建了自我跟踪实体。我已经在两个项目之间拆分了实体和上下文,以便我可以重用类型定义,因为我计划通过WCF运行客户端/服务器。

我的一个服务方法需要返回具有“ProductSku”子对象的“Product”对象的图形,这些对象又具有“ProductPrice”的子对象。选择标准将位于“Product”对象的“Name”属性和“ProductPriceObject”的“FinancialPeriodID”属性中。目前,我没有在搜索中包含该名称,但我在恢复图表方面遇到了问题。

如果我只是执行以下查询(请注意,此语法取自LinqPad而不是实际的应用程序代码)...

from product in Products.Include("Skus.PriceHistory")
select product

...然后我能够检索我需要的项目的完整对象图,当然此时没有过滤器。

如果相反,我引入过滤器如下...

from product in Products.Include("Skus.PriceHistory")
join sku in ProductSkus on product.ID equals sku.ProductID
join price in ProductPrices on sku.ID equals price.ProductSkuID
where price.FinancialPeriodID == 244
select product

...我期待得到的是“Product”对象,子“ProductSku”对象(位于“Product”的“Skus”集合中)和它们的“ProductPrice”对象(位于“ PriceHistory“ProductSku”的集合 - 但我只收回“Product”对象,“Skus”集合是空的。

我也尝试将查询编码为......

from product in Products.Include("Skus.PriceHistory")
from sku in product.Skus
from price in sku.PriceHistory
where price.FinancialPeriodID == 244
select product

......但这也没什么区别。

显然,我必须做错事。任何人都可以了解那些东西,因为我已经在这里玩了几个小时现在绕圈子!

答案

也许投影可以做到这一点?

看看Linq filter collection with EF

另一答案

编辑:

关于什么:

from product in Products.Include("Skus.PriceHistory")
where product.Skus.Any(s => s.PriceHistory.Any(p => p.FinancialPeriodID == 244))
select product

Include已经执行了所有必要的任务来填充导航属性,因此不需要条件的附加连接。更重要的是,任何手动连接或投影都将改变查询的形状,并且不会使用Include

还要注意条件只过滤产品。它不会过滤由Include加载的数据 - 您将获得至少一个具有财务期ID为244的价格历史的sku的所有产品,但这些产品将加载所有skus和价格历史记录。 EF目前不支持对include进行过滤。如果您还需要过滤关系,则必须执行单独的查询才能获得它们。

另一答案

拥有Include并不能保证拥有热切的加载,并且由于以下原因可能会无声地忽略它。在这个帖子中有更好的解释。您可以手动选择要加载的表格,例如

var result = from product in Products.Include("Skus.PriceHistory")
from sku in product.Skus
from price in sku.PriceHistory
where price.FinancialPeriodID == 244
select new { p=product, pricehistory = product.Skus.PriceHistory};
var products = results.select(pph => pph.product);

https://social.msdn.microsoft.com/Forums/en-US/76bf1f22-7674-4e1e-85d3-68d29404e8db/include-is-ignored-in-a-subquery?forum=adodotnetentityframework

  • Include仅适用于查询结果中的项目:在查询中最外层操作处投影的对象。
  • 结果的类型必须是实体类型。
  • 查询不能包含更改Include和最外层操作(即更改结果类型的GroupBy()或Select()操作)之间的结果类型的操作
  • Include采用的参数是以点分隔的导航属性路径,必须可以从最外层操作返回的类型实例导航
另一答案

自跟踪实体未启用延迟加载。这就是为什么集合在默认实体生成时不是空的而不是STE。实际上,如果在查询中使用它们,则Include从不加载相关实体。现在您的L2E查询不正确。我想你想做这样的事情:

from p in 
   (from product in Products
    select new 
    { 
       Product = product, 
       Skus = 
          from sku in product.Skus
          select new 
          { 
             Sku = sku, 
             Prices = 
                from price in sku.Prices
                where price.FinancialPeriodID == 244            
                select price
          }
    }).AsEnumerable()
select p.Product;

希望有所帮助

马修

以上是关于实体框架4:使用自我跟踪实体的过滤器进行预先加载(包括)的主要内容,如果未能解决你的问题,请参考以下文章

实体框架和预先加载以及使用 DDD 方法的企业应用程序

Entity Framework实体框架使用TrackerEnabledDbContext进行操作日志跟踪

自我跟踪实体的目的是啥?

对于庞大而复杂的对象图,使用自跟踪实体是不是有效?

实体框架代码优先多对多不使用 GUID 加载相关实体

延迟加载 - (实体框架)底层连接意外关闭