如何通过Linq将查询结果直接映射至ViewModel?
解决方案
错误原因分析
第一种写法的问题:
你直接将Include返回的IncludableQueryable<Pessoa, UnidadeRetirada>强制转换为IQueryable<PessoaVM>,这两种类型没有继承或兼容关系——前者是针对Pessoa实体的查询,后者是针对视图模型PessoaVM的查询,强制转换只会在运行时抛出类型转换异常,编译时无提示是因为显式强制转换绕过了编译器的类型检查。第二种写法的问题:
初始的query变量被错误赋值为类型不兼容的对象,后续调用Select时,编译器会认为p是PessoaVM类型,而非Pessoa实体,自然无法访问Pessoa的属性,导致类型转换报错。
正确实现方式
你需要先构建针对Pessoa实体的查询并关联所需表,再通过Select将实体投影为PessoaVM对象,无需任何强制转换:
IQueryable<PessoaVM> query = context.Set<Pessoa>() .Include(u => u.UnidadeRetirada) .Select(p => new PessoaVM() { id = p.id, cpf = p.cpf, nome = p.nome, nomeSocial = p.nomeSocial, status = p.status, createdDate = p.createdDate, UnidadeRetirada = p.UnidadeRetirada, idTipoDependente = p.idTipoDependente });
额外优化建议
如果PessoaVM中的UnidadeRetirada字段应该使用对应的视图模型(而非实体类),建议在投影时一并转换,避免将实体暴露到视图层:
IQueryable<PessoaVM> query = context.Set<Pessoa>() .Include(u => u.UnidadeRetirada) .Select(p => new PessoaVM() { id = p.id, cpf = p.cpf, nome = p.nome, nomeSocial = p.nomeSocial, status = p.status, createdDate = p.createdDate, UnidadeRetirada = new UnidadeRetiradaVM() { // 根据实际属性赋值 Id = p.UnidadeRetirada.Id, Nome = p.UnidadeRetirada.Nome }, idTipoDependente = p.idTipoDependente });
内容的提问来源于stack exchange,提问作者Saulo Torres
相关产品推荐
相关产品推荐

