【问题标题】:Avoid or control circular references in Entity Framework Core避免或控制 Entity Framework Core 中的循环引用
【发布时间】:2020-11-09 03:28:54
【问题描述】:

我真的完成了这个,但至少我想知道发生了什么。我们开始:

我的项目是一个带有 Code First Entity Framework Core 和 Angular 前端的 ASP.NET Core Web 应用程序。

我想控制何时加载引用的对象。它们可能很有用,但它们也可以在前端创建带有内部错误的循环引用。 (JSON 会无限长。)

型号:

class Book {
   public virtual ICollection<Page> Pages { get; set; }
   ...simple properties
}

class Page {
   public virtual Book Book { get; set; }
   ...simple properties
}

在此示例中,books 中的每本书都将有一个空/null Pages 列表。

using (var context = new MoneyStatsContext())
{
   var books = context.Books.Where(rule => rule.State == 1).ToList();
}

在此示例中,Pages 列表不为空,并且每个 Page 都将设置其 Book 属性。从而创建一个循环引用。

using (var context = new MoneyStatsContext())
{
   var books = context.Books.Where(rule => rule.State == 1).Include(x => x.Pages).ToList();
}

如何避免循环引用?除了创建一个新模型并手动指定每个属性之外,我真的没有其他(更简单的)选择吗?

.Select(new Book() {
   ...setting each property by hand
}

我发现的不起作用的解决方案:

  • 尝试将此设置为 false 和 true。似乎没有任何改变。
public MyContext()
{
   this.ChangeTracker.LazyLoadingEnabled = false;
}

  • 尝试在 Startup.cs 中指定此项,但 options 没有 SerializerSettings 属性。
services.AddMvc().AddJsonOptions(options =>
{
   options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core entity-framework-core


    【解决方案1】:

    假设您使用最新最好的 ASP .NET Core 3.1 和 System.Text.Json,要处理引用循环,您需要将“返回”切换到 Newtonsoft.Json(尽管值得一提的是 System.Text.Json 应该更快。 coming 也支持引用循环处理,正如 @Eric J. 在 cmets 中所写):

    services.AddControllers()
        .AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore)
    

    至于 EF 创建引用循环 - 它被称为relationship fixup,您对此无能为力(请参阅this 答案)。 AsNoTracking 可以提供一点帮助(但在 Include 的情况下则不然)。我个人的做法是从端点返回 DTO,而不是直接返回实体。

    UPD

    在 .NET 5.0 中引入了ReferenceHandler,所以接下来应该做的就是:

    services.AddControllersWithViews()
        .AddJsonOptions(options =>
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve)
    

    【讨论】:

    • .NET Framework 5.0 将支持循环引用github.com/dotnet/runtime/issues/30820
    • @EricJ。是的,但是还没有发布=(
    • 这并没有完全按照描述的那样工作,但是我没有提供足够的信息可能是错误的。 AddMvc() 返回一个没有 AddNewtonsoftJson 方法的 IMvcBuilder。我必须添加Microsoft.AspNetCore.Mvc.NewtonsoftJson nuget 包并使用AddControllers 而不是AddMvc。来源:stackoverflow.com/a/55666898/2563731
    猜你喜欢
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    相关资源
    最近更新 更多