EF Core中Linq Concat不同日期类型实体报错,如何在数据库端执行?
问题描述
我有两个需要在数据库端合并的实体:
public class Event { [Required] [StringLength(255)] public string Name { get; set; } public DateTime Datum { get; set; } } public class ClosingDay { [Required] [StringLength(50)] public string Name { get; set; } [Column(TypeName = "date")] public DateTime DatumVon { get; set; } }
两者的日期字段类型略有不同:Event的Datum是DateTime类型,ClosingDay的DatumVon是date类型(项目采用Code First模式,数据库中对应类型不同)。
我希望编写Linq语句在数据库端完成合并(不能在内存中处理),当前代码如下:
var tmp = ( from s in _context.ClosingDay select new CalendarDTO { Datum = Convert.ToDateTime(s.DatumVon), Name = Convert.ToString(s.Name) } ).Concat( from t in _context.Event select new CalendarDTO { Datum = Convert.ToDateTime(t.Datum), Name = Convert.ToString(t.Name) } );
其中CalendarDTO定义为:
public class CalendarDTO { public DateTime DatumVon { get; set; } public string Name { get; set; } }
仅设置CalendarDTO的Name字段时代码可正常运行,但即使使用Convert.ToDateTime转换日期字段,合并日期字段时仍报错:
Unable to translate set operation after client projection has been applied. Consider moving the set operation before the last 'Select' call.
请问如何在不进行内存合并的前提下解决该问题?
解决方案
错误核心原因是EF Core无法解析**投影(Select)之后执行集合操作(Concat)**的逻辑,必须先完成集合合并,再统一做投影转换。
修改后的代码如下:
var tmp = _context.ClosingDay .Select(s => new { Datum = s.DatumVon, s.Name }) .Concat(_context.Event.Select(t => new { Datum = t.Datum.Date, // 将DateTime截断为date类型,和ClosingDay的字段类型对齐 t.Name })) .Select(item => new CalendarDTO { DatumVon = item.Datum, Name = item.Name });
关键细节说明:
- 先合并再投影:先将两个实体的字段统一映射为匿名类型,执行
Concat完成数据库端的集合合并后,再统一转换成CalendarDTO,符合EF Core的查询转换规则。 - 日期类型对齐:对
Event的Datum调用Date属性,EF Core会生成对应的SQL日期截断语句,确保和ClosingDay的date类型在数据库端兼容,无需额外转换操作。 - 全程数据库端执行:所有逻辑都会被EF Core转换为SQL语句在数据库端执行,不会将数据加载到内存中处理。
内容的提问来源于stack exchange,提问作者Chi
相关产品推荐
相关产品推荐

