【问题标题】:How can I compare a nullable type date using user entered date?如何使用用户输入的日期比较可为空的类型日期?
【发布时间】:2015-03-30 02:32:35
【问题描述】:

我找不到如何将用户输入的日期与 EF6 创建的表格上的日期进行比较。我正在使用 LINQ 扩展搜索数据库,并尝试了多个编译建议,但在执行期间失败。

用户输入:

DateTime userdate;
DateTime.TryParse(search.Value, out userdate);

目前的尝试:

a = dbContext.Messages.Where(x => x.Date.Date == userdate.Date); // doesn't compile
a = dbContext.Messages.Where(x => x.Date.Value.Date == userdate.Date); // error # 4
a = dbContext.Messages.Where(x => x.Date.ToString() == userdate.Date.ToString()); // issue #2
a = dbContext.Messages.Where(x => x.Date.Value.ToString() == userdate.Date.ToString()); // issue #2
a = dbContext.Messages.Where(x => Object.Equals(x.Date, userdate.Date)); // throws error #1
a = dbContext.Messages.Where(x => Object.Equals(x.Date.Date, userdate.Date)); // throws error #1

我已经尝试搜索一百万次并找到可以编译的解决方案,但在执行时总是抛出错误。

有一个 ToString() 的版本可以工作,但它生成了一个长日期字符串,例如 May 12, 2005 00:00:00 并试图将我的用户日期变成一个长日期进行比较,这似乎会在搜索时产生过多的开销通过数百万条记录。

我对这里的想法很新鲜。

问题:

  1. 无法将类型 'System.Nullable``1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' 转换为类型 'System.Object'。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型。

  2. 没有找到任何匹配项,即使有确切的日期时间

  3. 神奇地突然起作用。

  4. LINQ to Entities 不支持指定的类型成员“日期”。仅支持初始化程序、实体成员和实体导航属性。

最终解决方案 根据选择的答案,我发现 SqlFunctions 类有一个映射到 T-SQL DateDiff 函数的 .DateDiff 方法。我用它来计算两个日期之间的天数,并只选择返回 0 的日期。这样我就可以比较日期,而无需在 SQL 端进行任何转换。

【问题讨论】:

  • 所以你说有错误... 这是什么错误
  • (直接在dbContext 上使用Where 而不是在上下文中的表上使用很奇怪,顺便说一句...)
  • 如果数据库值可以为空,为什么用户输入的值不能为空?
  • @JonSkeet,我正在尝试重新创建错误以发布...感谢您指出这一点,我试图缩短代码并起飞太多。用正确的代码更新了问题。
  • @David,我认为 TryParse 总是返回一个值,所以我认为它可以通过不将其声明为空来节省资源。

标签: c# entity-framework datetime entity-framework-6


【解决方案1】:

某些.NET 操作不能隐式转换为等效的SQL 操作,对于这些您需要使用System.Data.Entity.DbFunctions 中提供的方法。在您的具体示例中,您应该尝试使用TruncateTime 方法,而不是访问DateTime 实例的.Date 属性。

例子:

var date = userDate.Date;
dbSet.Where(x => DbFunctions.TruncateTime(x.Date) == date);

编辑:或者,SQL 服务器不一定支持与 .NET 相同的 datetime-values 范围,因此如果您的字符串解析失败并且您得到 DateTime.MinValue 它可能不是受支持的 datetime 值在您的 SQL 服务器中。

【讨论】:

  • 所以我查看了 System.Data.Entity.DbFunctions 的文档并找到了类 SqlFunctions。它具有许多我在编写 T-SQL 时经常使用的功能,这有助于我从 .NET 代码过渡到 T-SQL。使用它,我尝试了dbSet.Where(x => SqlFunctions.DateDiff("Day", x.Date.Value, userdate) == 0); .. 它奏效了。现在提问,因为我知道这也可以.Where(x => x.Date.Value == userdate.Date) 有任何性能差异吗?
  • 感谢您的帮助。我最终使用了上面列出的功能。我发现它不需要在 SQL 端进行任何转换,这应该会提高性能。
猜你喜欢
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 2013-06-12
  • 1970-01-01
相关资源
最近更新 更多