【问题标题】:EF Core 6.0 navigation property not loadingEF Core 6.0 导航属性未加载
【发布时间】:2022-01-04 11:16:53
【问题描述】:

我正在尝试构建一个简单的基于 ASP.NET Core 6 的 Web API。我从遵循 Microsoft 的最小 Web API 教程 https://docs.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-6.0 开始,它有效。然后我添加了我自己的带有导航属性的数据模型,使用https://docs.microsoft.com/en-us/ef/core/modeling/relationships 作为指导,但是当我执行查询时,该属性为空。

这是我的模型:

public class Author {
  public int Id { get; set; }
  public string Name { get; set; }
  public List<Book> Books { get; set; }
}

public class Book {
  public int Id { get; set; }
  public string Title { get; set; }
  public Author Author { get; set; }
}

我的 DbContext 如下:

public class LibraryDb : DbContext {
  public LibraryDb(DbContextOptions<LibraryDb> options) : base(options) {}
  public DbSet<Author> Authors => Set<Author>();
  public DbSet<Book> Books => Set<Book>();
}

还有我的申请:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSqlite<LibraryDb>("Data Source=Library.db");
var app = builder.Build();
app.MapGet("/authors", async (LibraryDb db) => await db.Authors.ToListAsync());
app.MapGet("/books", async (LibraryDb db) => await db.Books.ToListAsync());
app.Run();

运行“ef migrations add”和“ef database update”命令后,数据库结构如下:

CREATE TABLE "Authors" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Authors" PRIMARY KEY AUTOINCREMENT,
    "Name" TEXT NOT NULL
)
CREATE TABLE "Books" (
    "Id" INTEGER NOT NULL CONSTRAINT "PK_Books" PRIMARY KEY AUTOINCREMENT,
    "AuthorId" INTEGER NOT NULL,
    "Title" TEXT NOT NULL,
    CONSTRAINT "FK_Books_Authors_AuthorId" FOREIGN KEY ("AuthorId") REFERENCES "Authors" ("Id") ON DELETE CASCADE
)
CREATE INDEX "IX_Books_AuthorId" ON "Books" ("AuthorId")

我已经用几行填充了数据库(每本书都分配了一个 AuthorId),但这是调用我的“/authors”API 时的结果:

[{"id":1,"name":"Clive Barker","books":null},{"id":2,"name":"Stephen King","books":null}]

对于“/books”:

[{"id":1,"title":"Weaveworld","author":null},{"id":2,"title":"The Stand","author":null}]

“书籍”和“作者”字段为空。生成的 SQL 语句似乎没有进行任何连接 - 我做错了什么?如果我按照我在其他地方看到的建议将路由代码更改为 b.Authors.Include(x =&gt; x.Books).ToListAsync(),我会收到检测到对象循环的 JsonException。

【问题讨论】:

  • EF Core 使用延迟加载。仅在访问时加载相关实体。如果您想急切地加载相关实体,请使用Include

标签: c# sqlite asp.net-web-api


【解决方案1】:

Include 是正确的方法(至少其中之一 - 请参阅loading related data 文档)。所以添加回你的包含:

b.Authors
    .Include(x => x.Books)
    .ToListAsync()

下一个问题是由 EF 自动填充引用属性(称为关系修复)引起的,这将引入默认情况下序列化程序不处理的循环。您可以使用下一个设置更改序列化程序的行为:

builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});

我个人通常更喜欢从端点返回一些 DTO 而不是实体本身,这可以让您对返回进行更精细的控制,因此将查询结果映射到一些 DTO 也可以解决问题。

【讨论】:

  • 谢谢,我以后可能会使用 DTO,但这暂时有效。
猜你喜欢
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多