LINQ and AutoMapper

22,138

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();
Share:
22,138
Jammer
Author by

Jammer

Overworked dev!

Updated on February 09, 2020

Comments

  • Jammer
    Jammer over 4 years

    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 ...

  • Daniel Hilgarth
    Daniel Hilgarth over 11 years
    Using AsEnumerable() instead of ToList() is better as it still will perform deferred execution.
  • Aniket Inge
    Aniket Inge over 11 years
    That has to be the funniest name I've come across online!
  • Patryk Ćwiek
    Patryk Ćwiek over 11 years
    @Jammer But be careful when and where you dispose of the context. If you dispose the DbContext before materializing the collection (by e.g. calling ToList(), you'll get ObjectDisposedException when trying to do anything with the result.
  • Jammer
    Jammer about 11 years
    @Trustme-I'maDoctor for sure. I generally keep the same context around for the duration of a request and then dispose of it so I shouldn't see this exception! ... famous last words! Thanks!
  • CodeMonkeyKing
    CodeMonkeyKing over 10 years
    The Edit above says that execution is deferred, however, the the ToList() contradicts that. If deferred execution is desired, then the ToList() should be removed and the result returned should be IEnumerable<RoleDto>.
  • Patryk Ćwiek
    Patryk Ćwiek over 10 years
    @CodeMonkeyKing AsEnumerable would move it to LINQ to Objects domain and defer execution until the last ToList(), while the first example creates two lists one after another. That's the difference. :)