.NET6中EF Core通过Find/FindAsync获取嵌套对象的问题
问题概述
目标详情
我希望使用EF Core和SQLite从数据库中检索对象及其嵌套对象成员。
预期结果与实际结果
目前只有基础类型能正确实例化,而嵌套对象处于默认/空状态,列表也为空。我期望EF Core能执行额外查询,完整填充对象。
错误信息
未抛出任何错误,仅返回无效数据。
已尝试的解决方法
- 删除数据库并通过EF Core重建,试图修复多次更新后出现的小问题。
- 检查数据库,确认所需的所有嵌套数据都有有效条目。
- 尝试使用原生SQL,但在表连接时抛出“某对象已被引用”的错误。
简化复现步骤
我使用Microsoft.AspNetCore.Components.DataAnnotations.Validation 3.2.0-rc1.2023.4来使用ValidateComplexObjects特性。
FullName.cs
public class FullName { public ulong ID { get; set; } #region 姓名 [Display( Name = "First Name", AutoGenerateField = true, AutoGenerateFilter = true, Description = "The first name of a person", GroupName = "Name", Order = 2, Prompt = "Enter first name here", ShortName = "FName")] [MinLength(3, ErrorMessage = "First name can't be shorted than 3 letters")] [StringLength(100)] [Required] public string FirstName { get; set; } [Display( Name = "Last Name", AutoGenerateField = true, AutoGenerateFilter = true, Description = "The last name of a person", GroupName = "Name", Order = 1, Prompt = "Enter last name here", ShortName = "LName")] [MinLength(3, ErrorMessage = "Last name can't be shorted than 3 letters")] [StringLength(100)] [Required] public string LastName { get; set; } [Display( Name = "Middle Name", AutoGenerateField = true, AutoGenerateFilter = true, Description = "The middle name of a person", GroupName = "Name", Order = 50, Prompt = "Enter middle name here", ShortName = "MName")] [MinLength(3, ErrorMessage = "Middle name can't be shorted than 3 letters")] [StringLength(100)] [Required] public string MiddleName { get; set; } public string Name => $"{FirstName} {MiddleName} {LastName}"; #endregion }
Track.cs
// 记录可使用的赛道及其长度信息 public record Track(int Id, [Required] string Name, [Required]int distanceInMiles);
Person.cs
public class Person{ public ulong Id {get;set;} [ValidateComplexType] public FullName Name {get; set;} [Required] public string Description {get;set;} [ValidateComplexType] public List<Track> FriendsName {get;set;} }
ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<FullName> Names { get; set; } public DbSet<Person> Persons { get; set; } public DbSet<Track> Tracks { get; set; } }
ViewPeople.razor
@page "/Person/View/{id}" // 项目引用 @inject ApplicationDbContext ApplicationDbContext @if(validId){ @*Blah Blah HTML*@ } else { "Invalid Id Requested" } @code { Person person; [Parameter] public string id { get; set; } bool validId = false; protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); validId = ulong.TryParse(id, out var iId); person = await ApplicationDbContext.Persons.FindAsync(iId); validId = person is not null; } }
EF Core生成的表结构
Name表
| id | FirstName | MiddleName | LastName |
|---|---|---|---|
| 1 | John | Wittle | Door |
Track表
字段:id, Name, DistanceInMiles, PersonId
| id | Name | DistanceInMiles | PersonId |
|---|---|---|---|
| 1 | Honalulu | 12km | 1 |
| 2 | Honalulu 2 | 1km | x |
| 3 | Honalulu 6 | 4km | 1 |
Person表
字段:id, NameId, Description
| id | NameId | Description |
|---|---|---|
| 1 | 1 | "I am not a cadaver" |
预期与实际结果对比
预期结果
{ Id: 1, Name : { Id: 1, FirstName: "John", MiddleName: "Wittle", LastName: "Doe" }, Description: "I am not a cadaver", Tracks = [ {Id: 1, Name: "Honalulu", DistanceInMidles: 12km }, {Id: 2, Name: "Honalulu 2", DistanceInMidles: 1km }, {Id: 3, Name: "Honalulu 6", DistanceInMidles: 4km }, ] }
实际结果
{ Id: 1, Name : { Id: 0, FirstName: null, MiddleName: null, LastName: null }, Description: "I am not a cadaver", Tracks = [] }
内容的提问来源于stack exchange,提问作者Codelyok 13
相关产品推荐
相关产品推荐

