У меня есть IQueryable, объекты Entity Framework 4 которого я хотел бы спроецировать на их эквиваленты DTO. Один из таких объектов «Person» - это класс EF4, а соответствующий POCO PersonP - это класс, который я определил. Я использую Automapper для сопоставления между ними. Однако, когда я пробую следующий код:
IQueryable<Person> originalModel = _repo.QueryAll();
IQueryable<PersonP> projection = originalModel.Select(e => Mapper.Map<Person, PersonP>(e));
Проекция генерирует эту ошибку во время выполнения:
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.
Каков подходящий синтаксис для создания проекции IQueryable
с помощью Automapper? Спасибо.
PS Automapper настроен правильно - я использую его в других местах для преобразования туда и обратно между Person и PersonP, например Mapper.Map
правильно возвращает PersonP
объект.
РЕДАКТИРОВАТЬ (дополнительный код):
Я использую его для вспомогательной функции для привязки EF4 Entity POCOs (PersonP) к Telerik Grid - которая не будет должным образом сериализовать сами объекты, поскольку они содержат круговые ссылки (т.е. свойства навигации). Мой код выглядит следующим образом:
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...
}
метод .ToGridModel
является методом расширения для IQueryable
и возвращает сложный объект, который я не могу надежно проанализировать, поэтому это заставляет меня поверить, что я нужно выполнить фильтрацию после того, как я сделал проекцию для POCO.
ОБНОВЛЕНИЕ 2:
Пытаясь упростить ситуацию, я создал неуниверсальный метод вроде этого:
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 };
}
Этот код также не работает при создании проекции. Я заметил, что IQueryable.Select () имеет несколько перегрузок: Expression> является одной из них. Могу ли я представить этот вызов функции / делегата с помощью одной из этих перегрузок?