LINQ to Entities日期匹配报错:如何实现多日期筛选?
问题描述
需要将以下SQL转换为LINQ:
SELECT * FROM History WHERE CONVERT(VARCHAR(50), ActionDate, 112) IN ('20221116');
ActionDate字段包含日期和时间,仅需比较日期部分。现有日期字符串列表:
var someDates = new List<string>() { "11/16/2022" };
执行以下LINQ查询报错:
db.MyTable.Where(u => someDates.Contains(u.ActionDate.ToShortDateString())).ToList();
错误信息:
LINQ to Entities does not recognize the method 'System.String ToShortDateString()' method and this method cannot be translated into a store expression
使用AsEnumerable后仍报错:
db.MyTable.AsEnumerable().Where(u => someDates.Contains(u.ActionDate.ToShortDateString())).ToList();
错误信息:
This function can only be invoked from LINQ to Entities.
需解决该问题,实现多日期值筛选记录。
解决方案
方法1:将字符串日期转为DateTime集合,比较日期部分
把someDates的字符串转为DateTime类型,利用EF可识别的Date属性直接比较日期部分:
// 转换字符串日期为DateTime集合,建议用TryParseExact指定格式避免解析错误 var dateList = someDates.Select(s => DateTime.Parse(s)).ToList(); // 执行查询 var result = db.MyTable .Where(u => dateList.Contains(u.ActionDate.Date)) .ToList();
方法2:使用EF.Functions的日期函数(EF Core适用)
借助EF.Functions将数据库中ActionDate转为指定格式字符串,再和目标集合匹配:
// 将目标日期转为SQL 112格式(yyyyMMdd)的字符串 var formattedDates = someDates .Select(s => DateTime.Parse(s).ToString("yyyyMMdd")) .ToList(); // 用EF内置函数转换数据库日期格式后匹配 var result = db.MyTable .Where(u => formattedDates.Contains(EF.Functions.ConvertToString(u.ActionDate, "yyyyMMdd"))) .ToList();
方法3:构造日期范围查询
为每个目标日期构造“当天0点到次日0点”的范围,用Any组合筛选条件:
var dateRangeList = someDates.Select(s => { var date = DateTime.Parse(s); return new { Start = date.Date, End = date.Date.AddDays(1) }; }).ToList(); var result = db.MyTable .Where(u => dateRangeList.Any(r => u.ActionDate >= r.Start && u.ActionDate < r.End)) .ToList();
关于AsEnumerable报错的说明
之前用AsEnumerable报错,通常是查询中包含了只能在LINQ to Entities执行的操作(如关联查询、EF专属函数)。若要使用该方式,需确保所有EF专属逻辑都放在AsEnumerable之前,仅将内存处理放在之后:
// 先在数据库端筛选必要数据,再转内存处理 var result = db.MyTable .Select(u => new { u.Id, u.ActionDate, u.OtherField }) // 只取需要的字段减少数据量 .AsEnumerable() .Where(u => someDates.Contains(u.ActionDate.ToShortDateString())) .ToList();
此方法会先加载数据到内存再筛选,数据量大时性能较差,优先推荐前三种方法。
内容的提问来源于stack exchange,提问作者Frank Martin
相关产品推荐
相关产品推荐

