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

本文关键字:实体 框架 字符串 日期 比较 | 更新日期: 2023-09-27 18:11:39

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

Id int NOT NULL,
Date date NOT NULL

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

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

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

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

请注意,过滤器。日期是字符串。它不是DateTime结构

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

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

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

可以使用一些SqlFunctions方法

SqlFunctions.DatePart

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

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,那么创建并使用计算列是一种(非常)简单和干净的方法。

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

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