EF Core 2.1 Проблема преобразования чисел с плавающей запятой - PullRequest
0 голосов
/ 05 ноября 2018

Я столкнулся с проблемой генерации запросов в 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();

, что явно нехорошо, поскольку включает в себя вычисления на стороне DB. В моем случае запрос не критичен к производительности, но я все еще задаюсь вопросом: это ошибка или она считается функцией? Если так, то почему? Разве это не по крайней мере переломное изменение, которое должно было быть где-то объявлено? Или я просто слеп, чтобы найти его?

Я попытался найти подсказку в документации EF - заметки о выпуске, критические изменения, форумы ... но ничего не смог найти.

Буду признателен за любую подсказку относительно соответствующей документации, передового опыта или чего-либо еще, что может помочь в решении этой проблемы.

РЕДАКТИРОВАТЬ: основная команда EF приняла это как ошибку, которая будет исправлена ​​в 3.0.0 (https://github.com/aspnet/EntityFrameworkCore/issues/13908). Отлично! А пока у кого-нибудь есть идеи, что я могу сделать в качестве обходного пути? Нужно ли мне вручную искать все запросы, где это может произойти?

1 Ответ

0 голосов
/ 07 ноября 2018

Похоже, что это может быть ошибка в EF Core -

, если вы заметите, .Where(k => k.Grenze >= 17.1) заставит его сгенерировать sql-запрос, используя значение 17.1, поскольку он не генерирует его в параметризованный запрос - при работе с локальными переменными, хотя, похоже, он преобразует их в тот же тип, что и атрибут если сравнивать с сопоставленным, это вызывает проблемы с округлением.

Это в основном намеренное поведение из того, что я могу сказать, чтобы гарантировать типы компонентов в запросах, что позволяет лучше индексировать и т. Д., Хотя в случае float, double и decimal это вызывает потенциальные проблемы с округлением.

Было бы предложено поднять проблему для этого на GitHub, так как это может (и в вашем случае может) привести к неверным результатам запроса.

...