LINQ to SQL查询生成冗余SQL且返回多余字段如何优化
问题根因
你所用的ORM(通常为Entity Framework系列框架)无法解析Agent实体中自定义的DisplayName计算属性逻辑,无法将其内部的优先级判断转换为SQL层面的投影语句。因此ORM只能先将Agent表的全部字段查询到内存中,再在内存层面执行DisplayName的getter逻辑计算出值,再映射到AgentDto的Name字段,这就是SQL语句出现全字段查询的核心原因。
修复方案
直接将DisplayName的计算逻辑写入LINQ的Select投影中,不要调用实体的计算属性,修改你的GetPublishedAgent方法里的投影逻辑即可:
public IQueryable<Data.Dto.Agent.AgentDto> GetPublishedAgent() { var Agent = (from t in UnitOfWork.GetRepository<Template>().Get() join r in UnitOfWork.GetRepository<Regimen>().Get() on t.Id equals r.TemplateId join rp in UnitOfWork.GetRepository<RegimenPart>().Get() on r.Id equals rp.RegimenId join re in UnitOfWork.GetRepository<RegimenEntry>().Get() on rp.Id equals re.RegimenPartId join a in UnitOfWork.GetRepository<Agent>().Get() on re.AgentVersionKey equals a.VersionKey where t.IsCurrentVersion && t.Status == 7 && a.IsCurrentVersion && a.IsActive select new Data.Dto.Agent.AgentDto { // 直接把DisplayName的计算逻辑写在投影中 Name = !string.IsNullOrEmpty(a.RxNormTallMan) ? a.RxNormTallMan : !string.IsNullOrEmpty(a.NccnTallMan) ? a.NccnTallMan : a.Name, VersionKey= a.VersionKey }); Agent = Agent.Distinct(); return Agent; }
修改后ORM可以将这段三元判断逻辑转换为SQL中的CASE WHEN语句,最终生成的SQL只会查询RxNormTallMan、NccnTallMan、Name、VersionKey四个必要字段,不会再查询Agent表的全部字段。
另外你看到的两层嵌套SELECT是ORM处理Distinct和筛选条件时的正常生成逻辑,精简字段后不会对性能产生额外影响。
内容的提问来源于stack exchange,提问作者Jefferson
相关产品推荐
相关产品推荐

