我在Entity Framework Core 2.1中遇到了查询生成问题。
我有一个查询
var q = KostenSchweissen.Where(k => k.Grenze >= ewd)
.OrderBy(k => k.Grenze)
.FirstOrDefault();
其中KostenSchweissen.Grenze
是整数,而ewd
是浮点数。
因此,这将查找第一行,其“ Grenze”值大于或等于向下传递的值。 以前运行良好(EF Core 1.x,不确定2.0),但现在它正在生成查询(从SQL Server Profiler):
exec sp_executesql N'SELECT TOP(1) [k].[ID], [k].[Grenze], [k].[PreisEdelstahl], [k].[PreisNormalstahl]
FROM [KostenSchweissen] AS [k]
WHERE [k].[Grenze] >= @__ewd_0
ORDER BY [k].[Grenze]',N'@__ewd_0 smallint',@__ewd_0=17
其中ewd
为17.1。因此,这完全忽略了ewd是浮点数,显然会返回错误的成本。在查询中强制转换为double或float无效,唯一可以解决的方法是
var q = KostenSchweissen.Where(k => k.Grenze * 1.0 >= ewd)
.OrderBy(k => k.Grenze)
.FirstOrDefault();
这显然不好,因为它涉及数据库端计算。就我而言,该查询对性能不是很关键,但是我仍然想知道:这是一个错误还是被认为是一项功能?如果是这样,为什么?这至少不是应该在某个地方宣布的重大变化吗?还是我只是盲目的找到它?
我试图在EF文档中找到任何提示-版本说明,重大更改,论坛...,但找不到任何内容。
对于有关文档,最佳实践或任何其他可能有助于解决此问题的提示,我将不胜感激。
编辑:EF核心团队已接受此错误,此错误将在3.0.0(https://github.com/aspnet/EntityFrameworkCore/issues/13908)中修复。真好! 同时,是否有人对我可以解决的办法有任何想法?我是否必须手动查找所有可能发生这种情况的查询?
答案 0 :(得分:1)
这似乎是EF Core中的错误-
如果您注意到.Where(k => k.Grenze >= 17.1)
会导致它使用值17.1生成sql查询,因为它不会将其生成为参数化查询-使用局部变量时,尽管它似乎将它们转换为与类型相同的类型要比较的属性被映射,这会导致舍入问题。
根据我的判断,这主要是预期的行为,可确保查询之间的包含类型,允许进行更好的索引编制,尽管在float
,double
和decimal
的情况下,潜在的舍入问题。
建议在GitHub上提出一个问题,因为这可能会(并在您的情况下)导致错误的查询结果。