【问题标题】:Circular Reference with Include in .NET Core包含在 .NET Core 中的循环引用
【发布时间】:2019-09-06 08:11:08
【问题描述】:

我在 .NET 核心中使用如下代码

.Include(p => p.Company).ThenInclude(p => p.Country).ToList();

我的课程如下所示,


 public partial class Company
    {
        public Guid Id { get; set; }
        public string Name { get; set; }

        public virtual Country Country { get; set; }
    }

     public partial class Country
    {
      public Country()
        {

            Companies = new HashSet<Company>();
        }

        public Guid Id { get; set; }
        public string Name { get; set; }
         public string ShortCode { get; set; }

          public virtual ICollection<Company> Companies { get; set; }
    }

而且我希望只填充公司,然后填充公司中的国家/地区。但是我让公司在国家内部,然后在这些公司中填充国家等等,这导致响应延迟。

我已经尝试过 Google/StackOverFlow 上包含的不同示例。

【问题讨论】:

  • 请使用正确标签并提及您使用的EF Core版本。 Include() 是一种 EF Core 方法,不是 .NET Core 或 ASP.NET Core 的一部分。也发布您的代码 - 类是什么样的,实体是如何配置的? .SerializerSettings.ReferenceLoopHandling 与 EF Core 无关,是 JSON 设置
  • 您没有发布任何配置代码。像this one 这样的循环引用有很多问题。这个问题显示了所需的代码 - OnModelCreating 中的类、配置和 actual 查询,而不仅仅是其中的一部分。
  • 你是否在 EF 上启用了延迟加载?
  • @PanagiotisKanavos 如果有标准以外的东西,我会添加配置。我使用脚手架创建了模型和上下文,一切都非常标准。进一步感谢您指出问题,我面临的问题确实相关且几乎相同,但不幸的是,该问题没有可接受的答案。
  • EF Core 就是这样工作的,而且无法控制。此外,EF Core 本身在处理循环引用方面没有问题。实际问题在于Related data and serialization 文档主题中提到的序列化程序。如果您需要完全控制包含的内容,则不应使用实体类和Include 功能,而应使用 DTO/ViewModel 类和投影 (Select) 查询。

标签: .net-core entity-framework-core circular-reference


【解决方案1】:

这实际上不是问题。 EF 有所谓的“对象修复”。在内部,它使用对象缓存。当它为数据库查询结果构建实体实例时,它会将这些实体实例添加到对象缓存中,以便稍后提取这些对象,而不是再次发出相同的查询。

因为这个对象缓存,如果它已经存在实体实例对应一个关系,它会自动从对象缓存中填充那个关系。它不会永远发出一系列循环查询。

【讨论】:

  • 有没有办法在关系中禁用这种自动填充?
  • 如果你使用AsNoTracking(),我相信它会阻止这种行为,因为实体不会被添加到对象缓存中。但是,这并不可靠,就像您查询任何没有添加 AsNoTracking() 的内容一样,该查询中的实体将进入对象缓存,并且将被修复。换句话说,除非您端到端地控制所有查询,否则您不能保证在某些时候不会发生修复。也就是说,这是期望的行为。它使 EF 更高效。您很可能遇到了 XY 问题,您认为应该禁用修复。
  • 可能有更好的解决方案。例如,这个问题中的问题与序列化为 JSON 时的循环引用有关。解决方案是直接使用 DTO 而不是实体类。然后,您可以明确说明在序列化过程中遍历了哪些关系。
猜你喜欢
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多