EF Core 在复杂的 Where 子句上声明多个变量

Posted

技术标签:

【中文标题】EF Core 在复杂的 Where 子句上声明多个变量【英文标题】:EF Core declaring multiple variables on complex Where Clause 【发布时间】:2021-09-29 07:40:08 【问题描述】:

我有这个 LINQ Where 子句在 SQL 查询中声明 2 个变量

var parkingLotPrice = 
                _context.ParkingLotPrice
                    .Where(x => currentDate >= x.EffectiveDate && (currentDate <= x.ExpiryDate || x.ExpiryDate == null))
                    .ToQueryString();

它会生成这个 SQL 查询:

DECLARE @__currentDate_0 datetime2 = '2021-07-21T17:48:29.1106534-06:00';
DECLARE @__currentDate_1 datetime2 = '2021-07-21T17:48:29.1106534-06:00';

SELECT  [p].[ParkingLotId], 
        [p].[PriceScheduleId],
        [p].[EffectiveDate], 
        [p].[ExpiryDate]
FROM [ParkingLotPrice] AS [p]
WHERE (@__currentDate_0 >= [p].[EffectiveDate]) AND ((@__currentDate_1 <= [p].[ExpiryDate]) OR [p].[ExpiryDate] IS NULL)

注意:声明包含相同的值。

问题是(currentDate &lt;= x.ExpiryDate || x.ExpiryDate == null)

如果我删除 null 评估,它只会声明 1 个变量。

DECLARE @__currentDate_0 datetime2 = '2021-07-21T17:32:31.3980763-06:00';

SELECT  [p].[ParkingLotId], 
        [p].[PriceScheduleId], 
        [p].[EffectiveDate], 
        [p].[ExpiryDate]
FROM [ParkingLotPrice] AS [p]
WHERE (@__currentDate_0 >= [p].[EffectiveDate]) AND (@__currentDate_0 <= [p].[ExpiryDate])

有没有办法保持 Where 评估,但只声明 1 个变量?

【问题讨论】:

第二条sql在哪里生成?你也可以发一下吗? 添加了没有 null 评估 @Serge 的 SQL 查询 这有什么问题?它会返回错误的结果吗?我创建了数百个带空和不带空的查询,它们总是返回正确的结果。 你能帮我个忙吗?只是因为好奇,您可以通过像这样交换( x.ExpiryDate == null || (currentDate 感谢@Serge,查询仍然声明了 2 次​​span> 【参考方案1】:

它有什么问题?它会返回错误的结果吗?我创建了数百个带有 null 和 without 的查询,它们总是返回正确的结果。

我可以在您的查询中看到真正的问题。比较日期的方式。它也会比较时间。在某些情况下,它会返回错误的结果。我强烈建议您只比较日期

var parkingLotPrice =  _context.ParkingLotPrice
.Where(x => EF.Functions.DateDiffDay(x.EffectiveDate,currentDate) >=0  
&& (x.ExpiryDate == null || EF.Functions.DateDiffDay(currentDate,x.ExpiryDate)>=0 )).ToList();

或者如果你需要一些时间试试这个

var parkingLotPrice =  _context.ParkingLotPrice
.Where(x => EF.Functions.DateDiffMinute(x.EffectiveDate,currentDate) >=0  
&& (x.ExpiryDate == null || EF.Functions.DateDiffMinute(currentDate,x.ExpiryDate)>=0 )).ToList();

【讨论】:

结果还可以,但我的问题是为什么它声明变量2次。而且我也需要比较时间,不仅仅是日期。 @AlonsoUreñaq 我认为您必须向 EF 团队发送电子邮件。它只是一种算法。它不影响任何性能,对你有什么不同?

以上是关于EF Core 在复杂的 Where 子句上声明多个变量的主要内容,如果未能解决你的问题,请参考以下文章

实体框架:Count() 在大型 DbSet 和复杂的 WHERE 子句上非常慢

EF:包含 where 子句 [重复]

EF CORE中复杂类型的映射

EF CORE中复杂类型的映射

EF6 - 在 Where() 子句中使用 await 关键字

EF4 将 is null 子句添加到 where 子句