我有一個IQueryable,其實體框架4對象我想投影到他們的DTO等價物。一個這樣的對象'Person'是EF4類,相應的POCO PersonP是我定義的類。我正在使用Automapper在它們之間進行映射。然而,當我嘗試下面的代碼:IQueryable Lambda投影語法
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>
投影?謝謝。
P.S. Automapper配置正確 - 我在其他地方使用它來在Person和PersonP之間來回轉換,即Mapper.Map<Person, PersonP>(myPersonObject)
正確返回PersonP
對象。
EDIT(更多的代碼):
我用這一個輔助函數來EF4實體波蘇斯(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...
}
的.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>就是其中之一。我可以用這些重載表示這個函數/委託調用嗎?
即使使用常規方法代替AutoMapper,也會失敗。請在我的帖子中看到UPDATED2。 – Harper 2010-10-28 18:04:56
查看更新。非表達式不能轉換爲SQL。 – 2010-10-28 21:18:58
謝謝你的幫助。您的代碼有效(修正方法sig中的小錯字),但正如您所提到的,AutoMapper不適合此目的,並且不起作用。您能否解釋爲什麼我無法用新的ClientP {Id = ..}替換AutoMapper映射的技術原因 - 因爲兩者都返回一個ClientP對象? – Harper 2010-10-28 22:44:05