首页 > 解决方案 > Entity Framework Core 禁用递归检索 .Include() 函数中的信息

问题描述

该数据库有表 Machines、Wheels、Characteristics 和 Pilot。1条汽车记录包括1条关于Pilot的记录,4条车轮记录和几个特征。在我的模型类中,它看起来像这样:

public class Machines
{
    public int Id { get; set; }
    public string Description { get; set; }
    public string Color { get; set; }
    public int Weight { get; set; }
    public int Param { get; set; }

    public List<Characteristics> characteristics { get; set; }
    public List<Wheels> wheels { get; set; }
    public Pilot pilot { get; set; }
}
public class Characteristics
{
    public int Id { get; set; }
    public string Parameter { get; set; }
    public string Value { get; set; }
    public string Description { get; set; }

    public int MachineId { get; set; }
    [ForeignKey("MachineId")]
    public Machines machine{ get; set; }

}
public class Wheels
{
    public int Id { get; set; }
    public int Radius { get; set; }
    public int Weight { get; set; }
    public int MachineId { get; set; }

    [ForeignKey("MachineId")]
    public Machines machine{ get; set; }
}
public class Pilot
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; } 
    public int MachineId { get; set; }

    [ForeignKey("MachineId")]
    public Machines machine{ get; set; }
}

当我尝试下载有关这样一台机器的完整信息时:

 var car  = context.Machines.Where(x => x.Id == 2)
                        .Include(m=> m.Wheels)
                        .Include(m=>m.Charateristics)
                        .Include(m=>m.Pilot)
                        .FirstOrDefault();

作为回应,我得到一辆汽车,其中包含一名飞行员、一组所有特征和一组轮子。但同时,轮子数组再次包含有关汽车的信息,其中包括有关轮子的信息(但第二次没有汽车)。

它看起来像这样:

{
"id": 2,
"Description": "",
"Color": "red",
"Weight": 2000,
"Pilot": {
    "id": 1,
    "Name": "John",
    "Description": ""
}, 
"Wheels": [
    {
        "id": 7,
        "Radius": 14,
        "Weight": 5,
        "MachineId": 2, 
        "machine": {
            "id": 2,
            "Description": "",
            "Color": "red",
            "Weight": 2000,
            "Pilot": {
                "id": 1,
                "Name": "John",
                "Description": ""
            }, 
            "Wheels": [
                {
                    "id": 7,
                    "Radius": 14,
                    "Weight": 5,
                    "MachineId": 2
                },
...

如何在没有递归数据的情况下获取信息?

此外,请求需要很长时间(比 4 个单独的请求长得多)。微软网站说,如果你删除 virtual 关键字,你可以禁用下载。我清理了,但它没有帮助。同样在上下文中,我规定了this.ChangeTracker.LazyLoadingEnabled = false;但这也无济于事。

我还看到很多提到使用 .Load() 函数可以加快请求的执行,但我不太明白如何在我的情况下使用它。

更新

由于每个人都建议我包含 Newtonsoft.Json.ReferenceLoopHandling.Ignore 我将提供我的启动和上下文文件。事实上,我已经启用了这个。在我添加这个之前,我根本无法发送响应,并且在我添加它之后,它开始按照我的指示出现(参见 JSON 响应上部)。

我的背景:

    public DbSet<Machines> machines{ get; set; }
    public DbSet<Characteristics> characteristics{ get; set; }
    public DbSet<Wheels> wheels{ get; set; }
    public DbSet<Pilot> pilot{ get; set; }

    public dbContext(DbContextOptions<dbContext> options) : base(options)
    {
        this.ChangeTracker.LazyLoadingEnabled = false;
    }

我的启动:

public void ConfigureServices(IServiceCollection services)
{
   ...

   services.AddDbContext<dbContext>(options => { 

        options.UseMySql(Configuration.GetConnectionString("DefaultConnection"), 
        builder =>
        {
            builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
        });
        }); 

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

}

标签: asp.netentity-frameworkasp.net-core.net-coreentity-framework-core

解决方案


对于 asp.net core 2.x,您可以在 Startup.cs 中使用以下代码:

services.AddMvc().AddJsonOptions(options => 
         options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);

对于 asp.net core 3.x,您需要先安装,Microsoft.AspNetCore.Mvc.NewtonsoftJson然后使用以下代码:

services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

推荐阅读