我遇到了错误:
JsonSerializationException: Self referencing loop detected for property 'Subject' with type 'Project.Models.Subject'. Path 'data[0].Totals'.
当我加载一个 View ,其中的数据网格由 IEnumerable<Subject>
填充时,会发生这种情况模型。 Grid 是绑定(bind)到 View 模型的 DevExtreme DataGrid,如下所示:
@(Html.DevExtreme().DataGrid()
.DataSource(Model)
.Paging(paging =>
{
paging.Enabled(true);
paging.PageIndex(0);
paging.PageSize(20);
})
.Columns(columns =>
{
columns.Add().DataField("SubjectId");
... other fields
})
)
它是从 Controller 填充的,该 Controller 使用此功能从存储库中提取数据:
public async Task<IEnumerable<Subject>> GetSubjectsAsync()
{
return await _context.Subject.ToListAsync();
}
Subject 表与 Totals 具有 1:1 的关系,Totals 具有指向 Subject 的外键引用。项目中的模型如下所示(从 Scaffold-DbContext 生成):
public partial class Subject
{
public Guid SubjectId { get; set; }
public virtual Totals Totals { get; set; }
}
public partial class Totals
{
public Guid TotalsId { get; set; }
public virtual Subject Subject { get; set; }
}
由于这 2 个对象相互引用,因此在序列化时会导致循环。为了纠正这个问题,我将这个配置添加到我的 Startup.ConfigureServices 方法中:
services.AddMvc()
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
我从这个答案中得到:https://stackoverflow.com/a/40501464/7897176
但是,这并不能解决问题,当我加载涉及主题的 View 时,它仍然会导致错误。添加[JsonIgnore]
添加到 Totals 的 Subject 属性解决了这个问题,但我不想将它添加到我模型中的每个子属性,并且每当我从数据库更新我的模型时都必须重做。
最佳答案
JSON 序列化期间的自引用循环问题与 EFCore 如何加载相关数据 (docs) 有关。当您加载集合时,相关实体可能会自动填充,也可能不会自动填充,具体取决于之前是否已加载这些对象。它称为导航属性的自动修复。或者,可以通过 .Include()
预先加载它们。
每当您获得要序列化的实体的自引用图时,有几种选择:
Newtonsoft.Json.ReferenceLoopHandling.Ignore
( officially recommended )。它有效,但如果自引用发生在层次结构的深处,仍然会导致序列化过多的数据。[JsonIgnore]
导航属性的属性。如您所述,重新生成模型类时属性会消失。因此,它们的使用可能不方便。(最佳选择)预选一部分属性:
var minimallyNecessarySet= _nwind.Products.Select(p => new { p.ProductID, p.ProductName, p.UnitPrice, p.CategoryID }); return minimallyNecessarySet.ToList();
这种方法的优点是只序列化需要的数据。它与 DevExtreme 的
DataSourceLoader
兼容:return DataSourceLoader.Load(minimallyNecessarySet, loadOptions);
关于c# - 使用 Entity Framework Core 来自 Newtonsoft JsonSerializer 的自引用循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44555186/