C# 使用AutoMapper将LINQ查询结果映射到ViewModel对象

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

首先是一些背景知识。我正在使用Telerik MVC网格显示数据。网格期望一个IEnumerable被传递到他们的GridModel类中,我假设该类负责页面、排序、过滤等

为了避免在通过ajax将此数据作为JSON传递时出现循环引用,我需要将EF linq查询的结果映射到查看模型对象……AutoMapper将是我选择的方法,但我提出的涉及AutoMapper的唯一解决方案严重影响了性能

我有一个存储库,它将视图模型类型的IEnumerable返回给网格调用的操作方法

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的答案应该有效