I have an IQueryable whose Entity Framework 4 objects I would like to project to their DTO equivalents. One such object 'Person' is an EF4 class, and the corresponding POCO PersonP is a class I've defined. I am using Automapper to map between them. However, when I try the following code:
IQueryable<Person> originalModel = _repo.QueryAll();
IQueryable<PersonP> projection = originalModel.Select(e => Mapper.Map<Person, PersonP>(e));
The projection generates this error at runtime:
LINQ to Entities does not recognize the method 'TestSite.Models.PersonP Map[Person,PersonP](TestSite.DataLayer.Model.Person)' method, and this method cannot be translated into a store expression.
What is the appropriate syntax to create a IQueryable<PersonP>
projection using Automapper? Thank you.
P.S. Automapper is configured correctly - I use it in other places to convert back and forth between Person and PersonP, i.e. Mapper.Map<Person, PersonP>(myPersonObject)
correctly returns a PersonP
object.
EDIT (more code):
I'm using this for a helper function to bind EF4 Entity POCOs (PersonP) to a Telerik Grid - which will not serialize the entities themselves properly since they contain circular references (i.e. navigation properties). My code looks like this:
public static GridModel GetGridModel<TEntity, TPoco>(IRepository<TEntity> repo, GridState gridState) where TEntity : EntityObject
{
var originalModel = repo.QueryAll().ToGridModel(gridState);
var projection = originalModel.Select(e => Mapper.Map<TEntity, TPoco>(e));
return projection.ToGridModel(gridState); // applies filters, sorts, pages, etc...
}
the .ToGridModel
method is an extension method on IQueryable
and it returns a complex object which I cannot reliably parse - so this leads me to believe I have to perform the filtering after I've done the projection to POCOs.
UPDATE 2:
Trying to simplify things, I made a non-generic method like this:
public static GridModel GetGridModel2(IRepository<Client> repo, GridState gridState)
{
IQueryable<Client> originalModel = repo.QueryAll();
IQueryable<ClientP> projection = originalModel.Select(c => ClientToClientP(c));
return projection.ToGridModel(gridState);
}
private static ClientP ClientToClientP(Client c)
{
return new ClientP { Id = c.Id, FirstName = c.FirstName };
}
This code also fails when creating the projection. I notice that IQueryable.Select() has multiple overloads: Expression> being one of them. Could I represent this function/delegate call using one of these overloads?