EF Core顶级投影用具体类型:是否全在服务器执行且与映射等价?
EF Core投影到具体类型的服务器端评估问题
在你描述的这个场景里,方案2的所有评估操作都会在服务器端执行,而且和方案1功能完全等价。
原因说明
EF Core判断投影是否能全量服务器端执行的核心标准是:投影逻辑能否被完整翻译为SQL。你的场景满足这个条件:
PersonDto的构造函数参数都是直接对应实体的属性,没有任何客户端特有的逻辑(比如自定义方法、本地计算),EF Core可以直接把这个投影翻译为和匿名类型投影完全一致的SQL——只查询Id、Surname、Forename三个字段,同时OrderBy也会被转为SQL的ORDER BY子句,全程在数据库端完成排序和字段筛选。- 官方文档提到的“部分客户端评估”,是特指投影里包含EF Core无法翻译的逻辑时(比如调用只有客户端能跑的函数),才会先拉取基础数据到内存再做后续处理。你的场景里没有这类情况,所以不会触发客户端评估。
两个方案的差异
- 方案1是先把匿名类型的集合拉到内存,再在客户端把匿名对象映射成
PersonDto,多了一次内存转换的步骤。 - 方案2是EF Core直接让数据库返回对应字段,在数据读取阶段直接构建
PersonDto对象,省去了中间的匿名类型转换,效率略高,但最终得到的PersonDto集合和方案1完全一样。
代码示例
匿名类型投影(全服务器端执行)
var people = await context .People .OrderBy(x => x.Name) .Select(x => new { x.Id, x.Surname, x.Forename }) .ToListAsync();
方案1:先匿名类型再映射到具体类型
var people = (await context .People .OrderBy(x => x.Name) .Select(x => new { x.Id, x.Surname, x.Forename }) .ToListAsync()) .Select(x => new PersonDto(x.Id, x.Surname, x.Forename));
方案2:顶级投影直接使用具体类型
var people = await context .People .OrderBy(x => x.Name) .Select(x => new PersonDto(x.Id, x.Surname, x.Forename)) .ToListAsync();
内容的提问来源于stack exchange,提问作者lonix
相关产品推荐
相关产品推荐

