【问题标题】:Comparing date with string Entity Framework将日期与字符串实体框架进行比较
【发布时间】:2014-07-04 12:39:27
【问题描述】:

假设我有一个 SQL Server 数据库和一个如下所示的表:

Id int NOT NULL,
Date date NOT NULL

我有对应的实体框架模型:

public class Bundle
{
    public int Id {get; set;}
    public DateTime Date {get; set;}
}

用户可以键入可以是任何内容的字符串。我需要找到日期或日期的任何部分包含用户输入的字符串的所有项目。所以,基本上,我需要执行查询:

SELECT Id, Date
FROM Bundles
WHERE Date LIKE '%user_query_here%'

我的第一次尝试是

query.Where(b => b.Date.ToShortDateString().Contains(filter.Date))

这会引发 NotSupportedException,所以我尝试了这个:

query.Where(b => Convert.ToString(b.Date).Contains(filter.Date));

请注意,filter.Date 是字符串。它不是 DateTime 结构。

这也会引发异常。所以我的问题是如何执行上面写的查询?
PS:我无法在内存中执行过滤,这个表有数千行。

【问题讨论】:

  • 您确定您的要求吗?依赖日期的字符串表示对我来说真的很危险。如果客户端和服务器之间的文化不同怎么办?
  • 是的,我完全确定。而且我不担心问题,如果服务器和客户端的文化不同,就会发生这种情况。
  • 你知道这会很慢,对吧,因为它不会使用索引?如果您有一个日历表,您可以针对它运行日期搜索(小得多的表,索引中也有分隔列),然后可以将其作为常规范围查询的一​​部分加入......但我不确定如何在实体框架中处理。
  • 是的,我知道索引。这没什么大不了的,因为我在此列上没有索引。

标签: c# sql sql-server entity-framework


【解决方案1】:

遗憾的是,没有简单的方法可以使用 l2e 将日期时间转换为字符串。

您可以使用一些SqlFunctions 方法

SqlFunctions.DatePart

将返回一个表示日期的一部分的 int(例如年、月、日)。

SqlFunctions.StringConvert

可以帮助您将 int 转换为字符串(先将其转换为 double),然后您可以将其连接起来。

类似

.Where(b => (SqlFunctions.StringConvert((double)SqlFunctions.DatePart("y", b)) 
           + SqlFunctions.StringConvert((double)SqlFunctions.DatePart("m", b))
           //etc.
             ).Contains(filter.Date)

当然这是不可读的,而且真的不适合索引。

如果您使用 sql server,一种(更)更简单、更简洁的方法是创建和使用 计算列

你可以这样创建(如果你使用 Code First 和迁移,谷歌可以找到如何正确地做到这一点)

alter table add StringDate as convert(varchar, [Date], 112)//or another format, this will be yyyymmdd

如果你先使用代码,你必须用属性标记属性

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

那你就可以了

.Where(b => b.StringDate.Contains(filter.Date))

【讨论】:

  • 非常感谢您的解决方案。我使用了计算列解决方案。
猜你喜欢
  • 2014-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多