C# 使用AutoMapper将LINQ查询结果映射到ViewModel对象
首先是一些背景知识。我正在使用Telerik MVC网格显示数据。网格期望一个IEnumerable被传递到他们的GridModel类中,我假设该类负责页面、排序、过滤等 为了避免在通过ajax将此数据作为JSON传递时出现循环引用,我需要将EF linq查询的结果映射到查看模型对象……AutoMapper将是我选择的方法,但我提出的涉及AutoMapper的唯一解决方案严重影响了性能 我有一个存储库,它将视图模型类型的IEnumerable返回给网格调用的操作方法C# 使用AutoMapper将LINQ查询结果映射到ViewModel对象,c#,asp.net,asp.net-mvc,asp.net-mvc-3,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 3,首先是一些背景知识。我正在使用Telerik MVC网格显示数据。网格期望一个IEnumerable被传递到他们的GridModel类中,我假设该类负责页面、排序、过滤等 为了避免在通过ajax将此数据作为JSON传递时出现循环引用,我需要将EF linq查询的结果映射到查看模型对象……AutoMapper将是我选择的方法,但我提出的涉及AutoMapper的唯一解决方案严重影响了性能 我有一个存储库,它将视图模型类型的IEnumerable返回给网格调用的操作方法 public IEnumer
public IEnumerable<ResultViewModel> Search()
{
var person = _context.Persons;
//this works and is the best performance wise but could be made simpler with automapper
var result = person.Select(x => new ResultViewModel
{
FirstName = x.firstName,
LastName = x.lastName,
///etc...
});
//THIS IS SLOW but works
//var result = Mapper.Map<IEnumerable<Person>, IEnumerable<ResultViewModel>>(person);
//this does not work and errors at runtime
//var result = person.Select(x => Mapper.Map<Person, ResultViewModel>(x));
return result;
}
public IEnumerable Search()
{
var person=_context.person;
//这是最好的性能,但可以通过automapper简化
var result=person.Select(x=>newresultviewmodel
{
FirstName=x.FirstName,
LastName=x.LastName,
///等等。。。
});
//这是缓慢的,但工作
//var result=Mapper.Map(个人);
//这不起作用,并且在运行时出现错误
//var result=person.Select(x=>Mapper.Map(x));
返回结果;
}
关于如何在使用automapper使事情变得更简单的同时保持性能的任何想法。我假设使用automapper的慢版本是由枚举的
person
集合引起的…然后由telerik网格解析听起来像是存在一个Select(N+1)问题,循环中的每个项都加载相关属性,因此发出另一个Select查询
使用automapper不应该有任何性能问题
在您进行自动映射并断开IQueryable链之前,请尝试在person上调用
ToList()
。尝试ToList()仍然存在相同的问题…我请求的快速方式大约需要50毫秒…自动映射方式,需要700-850ms在您的上下文中关闭延迟加载,然后重试。关闭延迟加载使响应时间缩短了数百ms,但也阻止了我从相关服务器返回属性class@stephen776-那么您确实有一个选择N+1问题。使用.Include函数快速加载相关实体。person.Select(x=>Mapper.Map(x))
?@smartcaveman错误是:LINQ to entities无法识别该方法….,并且该方法无法转换为存储表达式这意味着尚未计算IQueryable
。jfar的答案应该有效