DbArithmeticExpression 参数必须具有数字通用类型

Posted

技术标签:

【中文标题】DbArithmeticExpression 参数必须具有数字通用类型【英文标题】:DbArithmeticExpression arguments must have a numeric common type 【发布时间】:2012-04-06 21:40:53 【问题描述】:
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.

请帮忙!

【问题讨论】:

clientDateTime - o.ClientDateTimeStamp的结果是什么? 通常应该是TimeSpan的对象,在EF中抛出异常。 【参考方案1】:

Entity Framework 6 及更早版本不支持 DateTime 的算术运算。您必须使用DbFunctions*。因此,对于您声明的第一部分,类似于:

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

注意DiffHours 方法接受Nullable&lt;DateTime&gt;

Entity Framwork 核心(与 Sql Server 一起使用时,可能是其他数据库提供程序)支持 DateTime AddXxx 函数(如 AddHours)。它们在 SQL 中被翻译成DATEADD

*EntityFunctions Entity Framework 版本 6 之前的版本。

【讨论】:

【参考方案2】:

我知道这是一个老问题,但在您的具体情况下,您不能像 @GertArnold 建议的那样使用 DBFunctions,而是将运算从 Lambda 中移出有问题的算术?

毕竟clientDateTimetime24 是固定值,因此不需要在每次迭代中重新计算它们的差异。

喜欢:

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();

如果您尝试将存储的日期时间偏移固定时间戳与其他日期时间进行比较,则通常可以进行此重构。

【讨论】:

我遇到过这种情况,这很有帮助。但是,此解决方案的范围非常有限,仅限于特定类型的问题。 @Zimano 它解决了 OPs 问题,而不需要他改变技术或求助于黑客。如果可以像这样重构,那么就这样做,如果不能,就像接受的答案那样做。【参考方案3】:

另外,如果性能不是真正的目标,您可以尝试使用AsEnumerable()。 所以,就像

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

添加 AsEnumerable() 会将 SQL 查询转换为实体,并允许在它们上运行 .Net 函数。欲了解更多信息,请查看about AsEnumerable

【讨论】:

以上是关于DbArithmeticExpression 参数必须具有数字通用类型的主要内容,如果未能解决你的问题,请参考以下文章

Python中的函数参数:位置参数默认参数可变参数关键字参数和命名关键字参数

Python的位置参数、默认参数、关键字参数、可变参数区别

参数定义的顺序必须是:必选参数默认参数可变参数命名关键字参数和关键字参数。

python函数参数类型:位置参数默认参数动态参数

实际参数、格式参数、虚拟参数以及实际参数和形式参数之间有啥区别? [复制]

17.Python函数函数参数:必备参数关键字参数默认参数不定长参数