大家好,
首先请允许我提前道歉。以下内容可能会有些发牢骚,但我对最新版(7.0.0-rc1-final)的EF7期望更高一些。如有任何评论或建议,请随时提出!
如果需要了解表/字段结构,欢迎提问,不过我希望从命名中就能清楚地看出来。
这是我的第一个EF7查询:
var enrichedProducts = this.productContext.Products
.AsNoTracking()
.Where(p => productNumbers.Contains(p.SAPProductNumber))
.Select(p => new
{
SAPProductNumber = p.SAPProductNumber,
DisplayName = p.DisplayName,
Brand = p.Brand,
Type = p.Type,
MultimediaValueEpochTime = p.ProductMultimedias
.Where(pm => pm.Visible == true
&& pm.ValueEpochTime != null)
.OrderByDescending(pm => pm.MainItem == true)
.ThenBy(pm => pm.SortOrder)
.Select(pm => pm.ValueEpochTime)
.FirstOrDefault()
})
.ToList();
这个查询引发了一个 SqlException:Incorrect syntax near '='。
原因是
OrderByDescending(pm => pm.MainItem == true)
。在数据库中,pm.MainItem
是一个可空的 bit 类型。EF7 把它翻译成 ORDER BY [pm].[MainItem] = 1 DESC
,但 SQL Server 不喜欢这种写法。EF6 的翻译更为复杂,但至少它能工作:
CASE WHEN (1 = [Extent2].[MainItem]) THEN cast(1 as bit) WHEN ( NOT ((1 = [Extent2].[MainItem]) AND ([Extent2].[MainItem] IS NOT NULL))) THEN cast(0 as bit) END AS [C1]
和
ORDER BY [Project1].[C1] DESC
但更糟糕的是,在从 OrderBy
中删除 == true
后,该查询仍然可以工作。令人惊讶的是,SQL Server 上执行了 9 次查询!很容易解释这个“9”。productNumbers
集合中有 8 个产品编号。哦天啊...更糟糕的是:这 8 个查询是完全相同的;它们甚至没有一个产品编号在它们的 where 子句中!而且这 8 个查询根本没有与 Products 表关联。这一切多么奇怪啊...
EF6 把它翻译成了一个带有
OUTER APPLY
和 SELECT TOP 1
的查询。尝试修复:
由于实体已经从一个现有的 EF6 项目中重用,我尽可能地使用流利的语言来替代注释。但没有改进。