EF Core 6.0 导航属性未加载
Posted
技术标签:
【中文标题】EF Core 6.0 导航属性未加载【英文标题】:EF Core 6.0 navigation property not loading 【发布时间】: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 => x.Books).ToListAsync()
,我会收到检测到对象循环的 JsonException。
【问题讨论】:
EF Core 使用延迟加载。仅在访问时加载相关实体。如果您想急切地加载相关实体,请使用Include
【参考方案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,但这暂时有效。以上是关于EF Core 6.0 导航属性未加载的主要内容,如果未能解决你的问题,请参考以下文章
EF Core 2 如何在 IdentityUser 上包含角色导航属性?
Ef core LazyLoading - 访问集合类型的嵌套导航属性引发 DetachedLazyLoadingWarning 错误