2011-09-27 40 views
2

的简单情况下我OperationContract实现是这样的:WCF + EF 4.1预先加载和序列化问题

public List<Directory> GetDirectories(bool includeFiles) 
{ 
    if (includeFiles) 
    { 
     return this.db.Directories.Include(e => e.Files).ToList(); 
    } 
    else 
    { 
     return this.db.Directories.ToList(); 
    } 
} 

其中GetDirectories(false);作品完全可以和GetDirectories(true);投用消息CommunicationObjectFaultedException

通信对象,System.ServiceModel.Channels.ServiceChannel, 不能用于通信,因为它处于Faulted状态。

显然,我的File实体具有参考Directory实体,以及Directory实体所拥有的文件的列表。首先,我认为这将是典型的循环参考陷阱,但在异常消息中我没有看到它。关于这个问题的任何想法?

+0

嗯,CommunicationObjectFaultedException通常不是你应该看到第一个异常(你打破你的渠道,并尝试使用它与下一个请求破碎后你得到它)我认为你应该搜索你丢失的第一个异常,它将包含实际的信息来解决问题。 – Giedrius

+0

使用调试器可以处理第一次机会异常,但CommunicationObjectFaultedException是引发的第一个异常。在其他情况下,我会得到关于循环引用的例外,但目前还没有。 –

+0

我仍然认为在出现故障之前有一个。任何自定义错误处理(如果没有,检查事件日志)?此外,您可以尝试使用SoapUI提出请求,不同的平台可能会帮助您找到缺失的部分。 – Giedrius

回答

1

这将是循环引用陷阱(here是一些有关这个主题)和理由你CommunicationObjectFaultedException将是这样的:

using (var client = new ServiceClient()) 
{ 
    data = client.GetDirectories(true); 
} 

的原因是,未处理的异常故障的通道和using试图在该故障通道上调用Close - 通道状态机中的无效转换(以及一个大的WCF奇怪)导致它成为您提到的异常。有很多方法来避免它,但基础是:

ServiceClient client = null; 

try 
{ 
    client = new ServiceClient(); 
    data = client.GetDirectories(true); 
} 
finally 
{ 
    if (client != null) 
    { 
     if (client.State == CommunicationState.Faulted) 
     { 
      client.Abort(); 
     } 
     else 
     { 
      client.Close(); 
     } 
    } 
} 
+0

立即命中。将'[IgnoreDataMember]'添加到File实体中的导航属性可以解决问题。有了你的建议,现在我将真正的例外视为循环参考。所以谢谢指出。 –