让我们假设我有一个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:我无法在内存中执行过滤,此表有数千行。
答案 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))