使用AutoMapper的ProjectTo方法时遇错误,请求技术支持
解决AutoMapper ProjectTo方法LINQ to Entities错误
错误说明
你遇到的具体错误为:LINQ to Entities 无法识别方法 'System.String ToString()' 方法,并且该方法无法转换为存储表达式。
错误原因
你的AutoMapper映射配置(Profile)中,存在将实体的非字符串类型属性(如int、decimal、DateTime等)通过ToString()方法直接映射到DTO字符串属性的逻辑。而EF Core在解析ProjectTo生成SQL查询时,无法把ToString()转换成数据库可执行的SQL表达式,因此抛出该错误。
解决方案
1. 依赖AutoMapper自动类型转换(推荐)
去掉映射配置中的手动ToString()调用,让AutoMapper自动处理类型转换,它会生成EF Core可识别的SQL转换语句(如CAST)。
示例配置:
public class ProductProfile : Profile { public ProductProfile() { CreateMap<Product, ProductListDto>() // 实体int类型Id映射到DTO的string类型IdStr,无需手动ToString() .ForMember(dest => dest.IdStr, opt => opt.MapFrom(src => src.Id)); } }
2. 使用EF Core可识别的表达式进行转换
如果需要自定义字符串格式(如货币、日期格式),可以用EF Core提供的EF.Functions中的方法,这些方法能被解析为对应的SQL函数:
using Microsoft.EntityFrameworkCore; public class ProductProfile : Profile { public ProductProfile() { CreateMap<Product, ProductListDto>() // 将decimal类型的Price转换为带两位小数的货币格式字符串 .ForMember(dest => dest.PriceStr, opt => opt.MapFrom(src => EF.Functions.ToString(src.Price, "C2"))); } }
3. 先加载数据到内存再映射(不推荐大数据量场景)
如果不需要在数据库层面投影,可以先将实体数据加载到内存,再用AutoMapper映射,这样ToString()就能正常执行,但会加载所有实体数据到内存,性能开销较大:
var queryable = await _unitOfWork.ProductRepository.GetList(query); return new Paging<ProductListDto> { Data = queryable.Data.ToList().Select(_mapper.Map<ProductListDto>).ToList() };
内容的提问来源于stack exchange,提问作者DeV1
相关产品推荐
相关产品推荐

