我需要將EF中的一些POCO實體投影到它們的縮減視圖模型表示中以傳遞給序列化程序。這種情況下的實體是裝運和申請單,並且具有0..1的關係。如果我不傳遞視圖模型,那麼它會在嘗試序列化Requisition和Shipment之間的循環引用時引發堆棧溢出異常。將嵌套實體嵌入到嵌套視圖模型中
return db.ShipmentRequisitions
.Include(c => c.Shipment)
.Select(r => new ViewModels.Requisition
{
ID = r.ID,
...
Shipment = r.Shipment != null ? new ViewModels.Shipment
{
ID = r.Shipment.ID,
...
} : null
}).AsQueryable();
如果貨件爲空,則在嘗試訪問r.Shipment.ID時會出現異常。我像上面添加了一個空檢查,現在得到以下異常。
無法創建類型'Api.ViewModels.Shipment'的常量值。 在此上下文中僅支持基本類型(如Int32,String和Guid) 。
這令我奇怪的,因爲它是相當愉快創建嵌套ViewModels.Shipment作爲選擇的一部分,之前我加空校驗,所以它必須有一些與此有關。
我可以在調用堆棧中看到一些EF,所以我在一個快速測試項目中嘗試了一下,只用直接的對象用純LINQ來嘗試它。
var user = users.Select(u => new ViewModel.User
{
Id = u.Id,
Profile = u.Profile != null ? new ViewModel.Profile
{
Id = u.Profile.Id
} : null
}).ToList();
令我驚訝的工作。我無法弄清楚這在第一個代碼示例中不起作用。
UPDATE
我發現,如果作爲一個選擇的一部分,我做這樣的事情:
.Select(r => new ViewModels.Requisition
{
ID = r.ID,
ShipmentDescription = r.Shipment.Description
})
這是有效的扁平化所需的出貨性質成一個單一的DTO。在設置Description屬性時,如果Shipment在任何記錄上爲空,我希望得到一個NullReferenceExcetion。然而它並沒有發生。 LINQ似乎抑制了這個異常,並且ShipmentDescription通過了null。它可以節省我對每個嵌套屬性進行內聯檢查。不幸的是,當創建一個嵌套的對象時,這似乎並沒有擴展到相同的東西。
同樣的問題在這裏:http://stackoverflow.com/questions/10904375/can-i-project-an-optional-reference-of-an-entity-into-an-optional-reference-of-t你最後如果使用例如'ID = r.Shipment.ID'當'左側ID'的例子就是BTW失敗*在一個數據庫中的記錄不爲空的*和'Shipment'是'NULL'。 – Slauma