使用包含(...)返回具有导航属性的实体时丢失连接

时间:2015-12-25 14:05:37

标签: c# entity-framework iis include

经过相当多的挖掘和混淆错误消息后,我已经到了这个样本(我认为这是再现问题的最小例子)。我几乎可以肯定地得出结论,问题的出现是由于实体与我正在返回的实体相关联。

[OperationContract]
[WebGet(UriTemplate = "Stations")]
List<Station> GetStations();

public List<Station> GetStations()
{
  List<Station> stations = new List<Station>();
  using (Context context = new Context())
    foreach (Station station in context.Stations.Include(element => element.Records))
      //stations.Add(station.Copy());
      stations.Add(station);

  return stations;
}

如果我使用 Copy()(它创建一个新的工作站实例)来复制该行,并复制除了它自己创建的记录之外的所有属性。但是,当我只是添加工作站而不创建副本时(无论我是否保留记录,使它们无效或设置为空列表),它都不能很好地滚动。

由于我使用了 Include(),因此处理的对象不再是问题。我得到的错误消息在控制台中如此说明。

  

http://localhost:25760/MyService.svc/Stations net :: ERR_CONNECTION_RESET

谷歌搜索给了我很多参考Apache(我在IIS上运行),PHP(我在.NET上构建它)和证书的安全问题(我没有使用任何和其他调用工作得很好。

所以我怀疑是错误信息来自混乱的计算机,或者我在设置中遗漏了某些内容。自动生成的类反映了我添加到表中的外键,看起来像这样。

alter table Records 
add constraint FkStationId 
foreign key (StationId) 
references Stations (Id)

public partial class Record
{
  public System.Guid Id { get; set; }
  public Nullable<System.Guid> StationId { get; set; }
  ...
  public virtual Station Station { get; set; }
}

public partial class Station
{
  [System.Diagnostics.CodeAnalysis.SuppressMessage(
    "Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  public Station() { this.Records = new HashSet<Record>(); }
  public System.Guid Id { get; set; }
  ...
  [System.Diagnostics.CodeAnalysis.SuppressMessage(
    "Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
  public virtual ICollection<Record> Records { get; set; }
}

我没有看到任何让我知道如何解决问题的想法。不应该发生此错误。另一方面 - 福岛也不应该发生。但确实如此。

1 个答案:

答案 0 :(得分:0)

最后我跑了。

  1. 关闭代理创建。
  2. 关闭延迟加载。
  3. 使虚拟属性可以忽略为序列化。
  4. 明确加载链接实体。
  5. 前两项是在上下文的构造函数中完成的。

    public partial class Context : DbContext
    {
      public Context() : base("name=ContextConnection")
      {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
      }
      ...
    }
    

    第三种方法是将导致循环依赖的虚拟属性之一归因于序列化无效。

    public partial class Station
    {
      ...
      [IgnoreDataMemeber]
      public virtual ICollection<Record> Records { get; set; }
    }
    

    最后一项是包含或省略导航属性(或不显示)。在这种情况下,将有关电台的信息插入每个记录是有意义的。但是,可以在没有记录的情况下显示这些电台。

    public List<Station> GetStations()
    {
      using (Context context = new Context())
        return context.Stations
          .ToList();
    }
    
    public List<Record> GetRecords()
    {
      using (Context context = new Context())
        return context.Records
          .Include(record => record.Station)
          .ToList();
    }
    

    话虽如此,会有龙。这种方法导致大量工作,因为它需要在每次重新创建时手动重新编辑自动生成的文件。所以我选择了Code First,而不是。