LINQ查询按DateTime字段排序无法翻译报错的解决求助
问题根因
报错的核心原因是EF Core无法将StudentDetails类的UpdateDate属性映射到数据库字段,无法生成对应的SQL语句,常见诱因如下:
StudentDetails类的UpdateDate属性只有get访问器,没有set访问器,EF Core默认不会映射无写入方法的属性- 代码存在基础语法错误:
StudentDetails类中public拼写为pubiic,Student类构造函数的int id和IEnumerable<StudentOwner> owner参数之间缺少逗号,会导致实体属性扫描映射失败
解决方案
方案1:修复属性映射(最推荐,无性能损失)
第一步先修正实体类的语法错误,给UpdateDate增加可写访问器,如果不希望外部修改可以用private set:
public class StudentDetails { public int Id {get; set;} public DateTime UpdateDate { get; set; } public string Comments { get; set; } public int StudentRef {get; set; } }
如果UpdateDate是数据库自动生成的(比如插入/更新时自动赋值),在你的DbContext的OnModelCreating方法中显式配置映射规则即可:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<StudentDetails>() .Property(d => d.UpdateDate) .ValueGeneratedOnAddOrUpdate(); // 可根据数据库实际生成规则调整 }
配置完成后原LINQ查询即可正常翻译成SQL执行。
方案2:重写查询为可翻译格式
如果不方便修改实体类定义,可以将查询改写为EF Core可识别的形式,先取最大更新时间再匹配数据:
baseQuery = baseQuery.Where(o => o.StudentDetails .OrderByDescending(s => s.UpdateDate) .Take(1) .Select(s => s.StudentRef) .First() == StudentSearchParams.StudentRef );
方案3:客户端评估(仅适合小数据量场景)
如果业务数据量很小,可以强制将数据加载到内存后再执行过滤,缺点是会加载所有符合前置条件的数据到内存,大数据量下性能极差:
// 先加载到内存再执行过滤 baseQuery = baseQuery.AsEnumerable() .Where(o => o.StudentDetails .OrderByDescending(s => s.UpdateDate) .First().StudentRef == StudentSearchParams.StudentRef ).AsQueryable();
内容的提问来源于stack exchange,提问作者Welsh King
相关产品推荐
相关产品推荐

