EF Core 6.0 导航 属性 未加载

EF Core 6.0 navigation property not loading

我正在尝试构建一个简单的 ASP.NET 基于 Core 6 的网站 API。我开始遵循 Microsoft 的最小网络 API 教程 https://docs.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-6.0, which works. Then I added my own data model with a navigation property, using 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),但这是调用我的“/作者”时的结果 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 => x.Books).ToListAsync(),我会收到一个 JsonException,指出检测到对象循环。

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

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

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

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

我个人通常更喜欢从端点 return 某些 DTO 而不是实体本身,这可以让您更精细地控制 return,因此将查询结果映射到某些 DTO 也可以修复问题。