实体框架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);
- 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:使用自我跟踪实体的过滤器进行预先加载(包括)的主要内容,如果未能解决你的问题,请参考以下文章