【发布时间】:2010-10-28 07:04:59
【问题描述】:
我有一个 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.
使用 Automapper 创建IQueryable<PersonP> 投影的适当语法是什么?谢谢。
附: Automapper 配置正确 - 我在其他地方使用它在 Person 和 PersonP 之间来回转换,即 Mapper.Map<Person, PersonP>(myPersonObject) 正确返回 PersonP 对象。
编辑(更多代码):
我使用它作为辅助函数,将 EF4 实体 POCO (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> 是其中之一。我可以使用这些重载之一来表示这个函数/委托调用吗?
【问题讨论】:
标签: linq-to-entities lambda linq-to-objects iqueryable projection