Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ and AutoMapper

I'm wondering if there is anything I can do to get this working as expected. This works fine in my code:

        var roles = _securityContext.Set<Role>();
        var roleList = new List<RoleDto>();
        foreach (var role in roles)
        {
            roleList.Add(Mapper.Map<Role, RoleDto>(role)); 
        }

        return roleList;

But changing this to:

        var roles = _securityContext.Set<Role>();

        return roles.Select(role => Mapper.Map<Role, RoleDto>(role)).ToList();

Results in an error I've not seen before:

"LINQ to Entities does not recognize the method 'Security.Dto.RoleDto MapRole,RoleDto' method, and this method cannot be translated into a store expression"

I'm not sure if I can even do anything about this'problem' ... arguably the method that works is more readable anyway ...

like image 762
Jammer Avatar asked Feb 08 '13 10:02

Jammer


People also ask

Why you should not use AutoMapper?

1. If you use the convention-based mapping and a property is later renamed that becomes a runtime error and a common source of annoying bugs. 2. If you don't use convention-based mapping (ie you explicitly map each property) then you are just using automapper to do your projection, which is unnecessary complexity.

What is AutoMapper in Entity Framework?

AutoMapper is a conventions-based mapping system that allows you to copy values from an instance of one class to an instance of another class using pre-defined maps.

When should I use AutoMapper?

AutoMapper is used whenever there are many data properties for objects, and we need to map them between the object of source class to the object of destination class, Along with the knowledge of data structure and algorithms, a developer is required to have excellent development skills as well.


1 Answers

You're operating on IQueryable, which tries to translate the method you supply into SQL. Obviously, it's not going to happen, as you're passing AutoMapper related magic. There's an easy solution, you have to force execution before mapping:

return roles.ToList().Select(role => Mapper.Map<Role, RoleDto>(role)).ToList();

[EDIT] As Daniel suggests in comments, you can always go from IQueryable to IEnumerable by calling AsEnumerable() and still defer execution:

return roles.AsEnumerable().Select(role => Mapper.Map<Role, RoleDto>(role)).ToList();
like image 101
Patryk Ćwiek Avatar answered Oct 16 '22 12:10

Patryk Ćwiek