2013-04-29 45 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