如何将C# LINQ投影逻辑移至独立方法且避免全表查询?
把投影逻辑抽成独立方法还能保持高效查询?当然可行
直接给你可行的实现方式,同时解释为什么之前的写法效率低:
正确的抽离方式:用表达式树
EF Core(或你使用的ORM框架)只能解析表达式树为SQL,普通方法做不到,所以之前的Map实例方法会导致全字段查询。把投影逻辑定义成表达式树,就能既抽离代码,又保留只查需要字段的高效性:
public static class DateProjections { // 把投影逻辑定义为表达式树,EF能解析成SQL public static readonly Expression<Func<Date, DateDto>> MapToDto = date => new DateDto() { Id = date.Id, EndDate = date.EndDate, EndHour = date.EndHour }; public static IQueryable<DateDto> Projection(this IQueryable<Date> source) { return source.Select(MapToDto); } }
如果需要动态调整投影逻辑(比如根据参数决定要不要加某个字段),可以写成返回表达式树的方法:
public static class DateProjections { public static Expression<Func<Date, DateDto>> GetMapToDtoExpression() { return date => new DateDto() { Id = date.Id, EndDate = date.EndDate, EndHour = date.EndHour }; } public static IQueryable<DateDto> Projection(this IQueryable<Date> source) { return source.Select(GetMapToDtoExpression()); } }
为什么第一种写法效率低?
你之前的Map是普通的扩展方法,ORM框架没法把方法体翻译成SQL,只能先把Date表的所有字段都查出来加载到内存,再在内存里调用Map转成DateDto,这就做了很多无用功。而用表达式树的话,ORM能直接生成只查Id、EndDate、EndHour的SQL,和你直接在Select里写逻辑的效率完全一样,还把代码抽离出来了,方便复用和维护。
内容的提问来源于stack exchange,提问作者Jaczura Zoltán
相关产品推荐
相关产品推荐

