繁体   English   中英

如何使用 Entity Framework Core 在 .NET Core WebAPI 中返回嵌套表(一对多)?

[英]How to return nested tables (one-to-many) in .NET Core WebAPI using Entity Framework Core?

我是 .NET 的新手,无法弄清楚为什么我会得到某些结果。 我发现了一些关于急切加载与延迟加载的结果,但没有一个解决方案有效。

我已经更改了列和数据的名称,因为它与工作相关,所以没有公共 repo 可用。

目前我的前端正在接收这样的数据:

{
    id: 234,
    column1: 1,
    column2: 2,
    column3: null
}

我希望它像这样在嵌套数组中返回一对多关系:

{
    id: 234,
    column1: 1,
    column2: 2,
    column3: [
        {
            table2Column1: 1,
            table2Column2: 2,
            table2Column3: 3,
        },
        {
            table2Column1: 7,
            table2Column2: 8,
            table2Column3: 9,
        },
    ]
}

以下是我的模型和 Controller 模式:

// Table1.cs

...
public int Id { get; set; }
public int Column1 { get; set; }
public int Column2 { get; set; }
public ICollection<Table2> Column3 { get; set; }
...

// Table2.cs
...
public int Id { get; set; }
public int Table2Column1 { get; set; }
public int Table2Column2 { get; set; }
public int Table2Column3 { get; set; }

public int Table1Id { get; set; }
public Table1 Table1 { get; set; }
...

//Table1Controller.cs
...
// GET: api/table1/{id}
[HttpGet("{id}")]
public Task<ActionResult<Table1>> GeTable1ById(int id)
{
    return await _context.Table1.FindAsync(id);
}
...

我发现信息说必须使用 Include 语句来强制预加载,所以我将 controller 更改为:

//Table1Controller.cs
...
// GET: api/table1/{id}
[HttpGet("{id}")]
public ActionResult<Table1> GeTable1ById(int id)
{
    return _context.Table1
                      .Include("Table2")
                      .Where(p => p.Id == id);
}
...

我尝试了一些变体,但错误的要点是我改变了数据的形状,所以它不适合 model... 尽管它应该是因为它应该预期来自链接表的 ICollection。 EFCore 在创建迁移和更新数据时没有问题,因为使用外键的 SQLServer 中的一切都是正确的。

返回的错误是: error CS0029: Cannot implicitly convert the type 'System.Linq.IQueryable<Project.Models.Table1>' to 'Microsoft.AspNetCore.Mvc.ActionResult<Project.Models.Table1>'

如何快速加载表格并将其连接到完整记录中? 谢谢您的帮助。



解决

Sergey 的原始答案有效但在前端循环引用失败(这是 EFCore 所要求的)。 所以你必须告诉 Json 序列化器忽略向后引用。 工作代码如下:

// Table2.cs 使用 System.Text.Json; 使用 System.Text.Json.Serializer; ... public int Id { 得到; 放; } public int Table2Column1 { get; 放; } public int Table2Column2 { 得到; 放; } public int Table2Column3 { 得到; 放; }

public int Table1Id { get; set; }
[JsonIgnore]
public Table1 Table1 { get; set; }
...

//Table1Controller.cs
...
// GET: api/table1/{id}
[HttpGet("{id}")]
public ActionResult<Table1> GeTable1ById(int id)
{
    return _context.Table1
                      .Include("Table2")
                      .Where(p => p.Id == id)
                      .FirstOrDefault();
}
...

您必须包含导航属性,而不是包含表名。 此查询应该有效:

var query =  _context.Table1
                .Include(t1 => t1.Column3)
                .Where(p => p.Id == id);

将您的操作更改为此:

HttpGet("{id}")]
public ActionResult<Table1> GeTable1ById(int id)
{
  
return _context.Table1
                      .Include(t=>t.Column3)
                      .Where(p => p.Id == id)
                      .FirstOrDefault();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM