gpt4 book ai didi

c# - 使用导航属性的 LINQ 查询生成多个 SELECT 语句

转载 作者:行者123 更新时间:2023-11-30 12:29:29 25 4
gpt4 key购买 nike

我有一个 POCO 域实体类,其中包含导航到相关记录的便捷方法。我正在使用 AdventureWorks2008R2 数据库来演示我试图完成的任务。所有这些查询都可以在 LINQPad 中运行以观察生成的 SQL 语句。

SalesOrderHeaders.Where(s => s.SalesOrderID == 43659)
.Single().SalesOrderDetails

此语句产生 2 个 SQL 语句。一个用于 SalesOrderHeader 记录,一个用于检索 SalesOrderDetails。现在考虑这个导航到另一个相关表的语句:

SalesOrderHeaders.Where(s => s.SalesOrderID == 43659)
.Single().SalesOrderDetails.Select(s => s.SpecialOfferProduct)

在检索到单个 SalesOrderHeader 记录后,域类将包含一个方便的属性,如下所示:

public IQueryable<SpecialOfferProduct> SpecialProducts
{
get
{
return SalesOrderDetails.Where(sod => sod.OrderQty > 3)
.Select(s => s.SpecialOfferProduct)
.AsQueryable();
}
}

此语句生成多个 SELECT 语句:SpecialOfferProduct 中的每条记录一个。我的问题是:为什么导航属性不生成单个 SELECT 语句?这是一个巨大的性能问题,因为它会产生很多不必要的喋喋不休。我可以使用 LINQ SQL 语法,但那只能在使用存储库进行原始查询时使用。在这种情况下,我有一个 SalesOrderHeader 对象的实例,并且无权访问类中的 Context 或 Repository。有没有办法强制它使用 JOIN 创建单个 SELECT 语句?

如果没有办法做到这一点,我正在考虑在我的存储库中创建一个额外的方法来填充这些属性。问题是我有 2 个步骤:1 检索 SalesOrderHeader 对象,然后另一个使用适当的 LINQ 语句填充附加属性,该语句将强制 JOIN 语法。

最佳答案

如评论中所述,您需要 Include方法:

SalesOrderHeaders.Include(s => s.SalesOrderDetails
.Select(d => d.SpecialOfferProduct))
.Where(s => s.SalesOrderID == 43659)
.Single().SalesOrderDetails

这将加入所需的数据(在 SQL 中)并填充导航属性。

但是请注意,您不能使用如下语法

.Include(s => s.SalesOrderDetails.Where(sod => sod.OrderQty > 3)
.Select(d => d.SpecialOfferProduct))

这似乎会部分填充 SalesOrderDetails。 EF 团队收到了实现此更改的请求,但到目前为止,尚未完成。

另一方面,将 SpecialProducts 作为 IQueryable 返回是没有用的,因为对集合的后续查询无论如何都不会转换为 SQL。首先,您只能在内存语句中访问属性,而不能在 linq-to-enitites 查询中访问(EF 无法将属性转换为 SQL)。

关于c# - 使用导航属性的 LINQ 查询生成多个 SELECT 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18414646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com