Аргументы DbArithmeticExpression должны иметь числовой общий тип - PullRequest
111 голосов
/ 22 марта 2012
TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);    

// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
    o => (clientDateTime - o.ClientDateTimeStamp < time24) && 
          o.ClientDateTimeStamp.TimeOfDay > time18 && 
          clientDateTime.TimeOfDay < time18 && 
          o.UserID == userid).ToList(); 

Это выражение Linq выдает это исключение:

DbArithmeticExpression arguments must have a numeric common type.

Пожалуйста, помогите!

Ответы [ 3 ]

227 голосов
/ 25 марта 2012

Арифметика с DateTime не поддерживается в Entity Framework 6 и более ранних версиях. Вы должны использовать DbFunctions *. Итак, для первой части вашего заявления, что-то вроде:

var sleeps = context.Sleeps(o =>
    DbFunctions.DiffHours(o.ClientDateTimeStamp, clientDateTime) < 24);

Обратите внимание, что метод DiffHours принимает Nullable<DateTime>.

Ядро Entity Framwork (при использовании с Sql Server, возможно, другими поставщиками БД) поддерживает функции DateTime AddXxx (например, AddHours). Они переведены на DATEADD в SQL.

*EntityFunctions до версии 6 Entity Framework.

2 голосов
/ 09 июля 2015

Я знаю, что это старый вопрос, но в вашем конкретном случае вместо использования DBFunctions, как предложено @GertArnold, не могли бы вы просто инвертировать операцию, чтобы убрать рассматриваемую арифметику из лямбды?

В конце концов clientDateTime и time24 являются фиксированными значениями, поэтому нет необходимости пересчитывать их разность на каждой итерации.

Like:

TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);    

var clientdtminus24 = clientDateTime - time24;

// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
    o => (clientdtminus24 < o.ClientDateTimeStamp) && 
          o.ClientDateTimeStamp.TimeOfDay > time18 && 
          clientDateTime.TimeOfDay < time18 && 
          o.UserID == userid).ToList();

Этот рефакторинг обычно возможен, еслиВы пытаетесь сравнить сохраненную дату и время, сдвинутые на временную метку, с другой датой.

1 голос
/ 11 июля 2018

С другой стороны, если производительность не является истинной целью, вы можете попробовать использовать AsEnumerable(). Итак, это будет похоже на

List<Model.Sleep> sleeps = context.Sleeps.AsEnumerable().Where(....

Добавление AsEnumerable () преобразует SQL-запрос в сущность и позволяет запускать на них функции .Net. Для получения дополнительной информации, проверьте здесь о AsEnumerable

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...