2012-08-01 62 views
5

我在EF Code First上下文中使用了一些POCO對象。所以,當我用數據填充它們時,實際上我正在處理EF代理對象而不是POCO本身。將EF代理對象轉換爲原始POCO對象的最佳方式是什麼?

我有一個ASP.NET MVC4 ApiController返回我的POCO對象,我將在我的客戶端應用程序消耗。

我的「GET」方法看起來是這樣的:

// GET api/Clients/5 
    public Client GetClient(int id) 
    { 
     Client client = db.Clients.Find(id); 
     if (client == null) 
     { 
      throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); 
     } 

     return client; 
    } 

這並不實際工作,因爲當串行嘗試序列Client對象,它實際上是在處理與EF代理的版本,這將導致它打嗝。見Can an ApiController return an object with a collection of other objects?

所以,我可以這樣做是爲了我的DbContext關閉代理代:

db.Configuration.ProxyCreationEnabled = false; 

這保證了我處理與POCO,而不是代理。但是,現在我的Client類中的大多數成員都沒有填充,因爲它是EF代理懶惰加載這些給我的。

所以我真正想要的是使用EF代理類來獲取數據,然後在最後一分鐘從我的方法返回原來的POCO。

我怎麼能做到這一點,而無需手動從頭創建整個對象(包括任何嵌套對象)的代碼?當然,必須有一個簡單的方法 - 或者至少是某種助手類?

回答

3

您的問題涉及如何設計應用程序的體系結構。從技術上講,在一個應用程序中有更多的模型:不同層的域模型,數據傳輸對象或視圖模型:業務邏輯層,分佈層和表示層。模型的

濫用在ASP.NET MVC中,我經常看到使用領域模型(從EF)作爲視圖模型,因爲在某些情況下是正確的域模型視圖模型是不夠你的UI。但實際上,它與使用複雜的用戶界面非常不同,例如:網格,可能需要多個域模型才能在一個視圖模型中合併,以便爲您的用戶界面提供數據。

與分佈層,asp.net web api類似,消費者可能需要多個領域模型來做一些事情。它通常不是100%的域模型作爲數據傳輸對象。

因此,對於關注的分離,它會建議你應該創建與域對象(從EF POCO對象)單獨DTO的對象,即使它被映射1:1的屬性。

例如,如果您有客戶域模型,則需要擁有CustomerDto。

您可以手動映射或使用工具,如AutoMapper,映射你的域模型到DTO模式。

用這種方法你也可以避免你的問題的東西。

+2

+1暴露DTO的遠程客戶端是最好的一段路要走。它使您可以完全控制通過線路發送的數據。 – 2012-08-01 15:53:57

+0

謝謝,我會檢查AutoMapper - 這聽起來就像我正在尋找的「某種助手類」。 – 2012-08-01 22:13:46

1

我知道,你得到的答案,但是,可能你會想看看這個:

的POCO代理類型不能直接序列化或由Windows Communication Foundation的反序列化(WCF) ,因爲DataContractSerializer序列化引擎只能序列化和反序列化已知類型。代理類型不是已知的類型。有關更多信息,請參閱使用POCO實體主題中的序列化POCO代理部分。要將POCO代理序列化爲POCO實體,請在序列化期間使用ProxyDataContractResolver類將代理類型映射到POCO類型。

http://msdn.microsoft.com/en-us/library/vstudio/ee705457(v=vs.100).aspx

+0

有趣,謝謝。 – 2013-12-17 15:43:20

相關問題