将日期与字符串实体框架进行比较

时间:2014-07-04 12:39:27

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

让我们假设我有一个SQL Server数据库和一个看起来像这样的表:

Id int NOT NULL,
Date date NOT NULL

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

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

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

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:我无法在内存中执行过滤,此表有数千行。

1 个答案:

答案 0 :(得分:5)

遗憾的是,没有简单的方法可以将日期时间转换为带有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 ,那么(更简单)更简洁,更简洁的方法就是创建并使用计算列

您可以像这样创建它(如果您使用代码优先和迁移,Google可以找到如何正确执行此操作)

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