2013-04-29 50 views
0

我正在使用EF和WCF。 我想使用由EF生成的對象作爲從Web服務方法返回的對象。 在OperationContract的方法,我做這樣的事情:如何將EF對象作爲WCF方法返回結果

try 
{ 
    b = (from bon in this.znDbContext.BonSet 
     where bon.IdPr == pa.IdPr 
     select bon).First();  
} 
catch (InvalidOperationException) { } 

return b; 

如果我調用Web服務方法,我會收到以下錯誤信息:

無法調用服務。可能的原因:該服務離線 或無法訪問;客戶端配置與 代理不匹配;現有的代理無效。有關更多詳細信息,請參閱 的堆棧跟蹤。您可以嘗試通過啓動新代理,將 恢復爲默認配置或刷新服務來進行恢復。

在google上搜索我找到了解決此問題的解決方案。已添加此語句:

this.znDbContext.Configuration.ProxyCreationEnabled = false; 

以這種方式,客戶端從Web服務方法接收響應,但每個內部對象都有空值。 如果我刪除前面的語句並執行對象的副本(逐個字段),客戶端會收到正確設置了內部對象(即boni.User)的對象。 比如我做的:

boni = new Bon(); 
User u = new User(); 
boni.IdPr = b.IdPr; 
boni.Date = b.Date; 
boni.System = b.System; 
u.Id = b.User.Id; 
u.Name = b.User.Name; 
u.Login = b.User.Login; 
boni.User = u; 
return boni; 

有一種方法返回一個完整的對象與所有內部對象不執行類似「克隆」操作? 我想從DbContext中分離對象以獲得避免手動複製操作的新對象。

這個問題的理論解釋非常受歡迎。

回答

3

當您將ORM代理與DTO混合使用時,會出現此問題。這個問題/解決方案在WCF中很常見,也適用於任何其他ORM,如nHibernate。

如果您從ORM中獲取實體,它通常會返回一個能夠從數據庫延遲加載數據的代理。例如,它只會在第一次訪問時加載屬性的實際數據。 這意味着,如果你從EM獲取一個「Bon」對象,它會給你一個「BonProxy」對象。顯然,「BonProxy」預計不會在DataContract(你也不能傳遞到客戶端,你不能就能夠做任何進一步的延遲加載客戶端)

解決方案: 把你複雜的實體進入DTOs(即將字段複製到現場)並僅通過線路發送DTO。這也是序列化所必需的 - 您可以控制它以避免循環引用。

+0

我已經使用這個外部工具來自動生成DTOs對象:http://entitiestodtos.codeplex.com/wikipage?title=Using%20EntitiesToDTOs.v3.%2a&referringTitle=Using%20EntitiesToDTOs 現在工作得很好。 我希望它可以有用。 – f0rb1dd3n403 2013-04-30 23:16:32