使用 Include(...) 返回具有导航属性的实体时失去连接
Losing connection when returning entity with navigational properties using 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; }
}
我没有看到任何关于如何排除故障的想法。这个错误不应该发生。另一方面——福岛也不应该发生。但确实如此。
我终于明白了 运行。
- 关闭代理创建。
- 关闭延迟加载。
- 使虚拟 属性 可忽略以进行序列化。
- 显式加载链接实体。
前两项在上下文的构造函数中完成。
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();
}
话说回来,会有龙。这种方法会导致大量工作,因为每次 re-created 时都需要手动 re-edit auto-generated 文件。所以我选择了代码优先。
在深入挖掘和混淆错误消息之后,我找到了这个示例(我认为这是重现该问题的最小示例)。我几乎可以肯定地得出结论,问题的出现是由于与我要返回的实体相关联的实体。
[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; }
}
我没有看到任何关于如何排除故障的想法。这个错误不应该发生。另一方面——福岛也不应该发生。但确实如此。
我终于明白了 运行。
- 关闭代理创建。
- 关闭延迟加载。
- 使虚拟 属性 可忽略以进行序列化。
- 显式加载链接实体。
前两项在上下文的构造函数中完成。
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();
}
话说回来,会有龙。这种方法会导致大量工作,因为每次 re-created 时都需要手动 re-edit auto-generated 文件。所以我选择了代码优先。