Har*_*per 6 lambda linq-to-objects linq-to-entities iqueryable projection
我有一个IQueryable,其实体框架4对象我想投影到他们的DTO等价物.一个这样的对象'Person'是EF4类,相应的POCO PersonP是我定义的类.我正在使用Automapper在它们之间进行映射.但是,当我尝试以下代码时:
IQueryable<Person> originalModel = _repo.QueryAll();
IQueryable<PersonP> projection = originalModel.Select(e => Mapper.Map<Person, PersonP>(e));
Run Code Online (Sandbox Code Playgroud)
投影在运行时生成此错误:
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.
Run Code Online (Sandbox Code Playgroud)
IQueryable<PersonP>
使用Automapper 创建投影的合适语法是什么?谢谢.
PS Automapper配置正确 - 我在其他地方使用它在Person和PersonP之间来回转换,即Mapper.Map<Person, PersonP>(myPersonObject)
正确返回一个PersonP
对象.
编辑(更多代码):
我正在使用它来帮助函数将EF4实体POCO(PersonP)绑定到Telerik网格 - 由于它们包含循环引用(即导航属性),因此不会正确地序列化实体本身.我的代码看起来像这样:
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...
}
Run Code Online (Sandbox Code Playgroud)
该.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 };
}
Run Code Online (Sandbox Code Playgroud)
创建投影时,此代码也会失败.我注意到IQueryable.Select()有多个重载:Expression>是其中之一.我可以使用其中一个重载来表示此函数/委托调用吗?
Nat*_*han 11
AutoMapper的作者现在已经解决了这个问题:http://lostechies.com/jimmybogard/2011/02/09/autoprojecting-linq-queries/
他提供了一个实现,它采用所需的投影和查询,并仅查询数据库中投影映射所需的字段.
另外,请参阅Paul Hiles 的后续文章,了解一些缓存方面的改进.
希望这可以帮助.
使用Automapper创建IQueryable投影的合适语法是什么?
没有一个.Automapper不会这样做.这是这项工作的错误工具.
可以创建一个类似Automapper的工具来为查询投影做类似的事情.我过去曾考虑过它,但总是得出结论,使用它的代码比投影的可读性差.我不想在代码读取时间内优化代码写入时间.
您更新的代码不起作用,因为它不是表达式.如果你这样做:
private static Expression<Func<Client, ClientP>> ClientP ClientToClientP()
{
return c => new ClientP { Id = c.Id, FirstName = c.FirstName };
}
Run Code Online (Sandbox Code Playgroud)
...然后:
IQueryable<Client> originalModel = repo.QueryAll();
Expression<Func<Client, ClientP>> exp = ClientToClientP();
IQueryable<ClientP> projection = originalModel.Select(exp);
Run Code Online (Sandbox Code Playgroud)
......那就行了.