ef core 如何一次从具有外键的不同表中获取数据? (数据库优先)
Posted
技术标签:
【中文标题】ef core 如何一次从具有外键的不同表中获取数据? (数据库优先)【英文标题】:ef core how to get data from different tables with foreign keys at once? (DB first) 【发布时间】:2021-05-09 21:34:06 【问题描述】:我的项目中有两个表,“教育者”和“教育者许可证”。
教师许可证依赖于具有外键的教师表。 (数据库优先)
我的数据库中带有 id 的外键: (教育者可以有N个执照)
我的教育者模型如下:
public class Educator
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[JsonIgnore]
public int id get; set;
[JsonIgnore]
public int CompanyId get; set;
public string PublicId get; set;
public string Name get; set;
public string PhoneNumber get; set;
public int Password get; set;
public bool Gender get; set;
public string AdminNote get; set;
public List<EducatorLicense> EducatorLicense get; set;
public bool Status get; set;
public TimestampsModel Timestamps get; set;
我的教育者许可模式,例如:
public class EducatorLicense
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id get; set;
[JsonIgnore]
public int EducatorId get; set;
public string LicenseType get; set;
我的 DbContext:
protected override void OnModelCreating(ModelBuilder model)
model.Entity<Educator>(builder =>
builder.ToTable("educators");
builder.Property(p => p.id)
.ValueGeneratedOnAdd();
builder.OwnsOne(c => c.Timestamps,
a =>
a.Property(p => p.CreatedAt).HasColumnName("createdAt");
a.Property(p => p.UpdatedAt).HasColumnName("updatedAt");
);
builder.HasOne(d => d.EducatorLicense)
.WithMany()
.HasForeignKey(d => d.Id)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("educatorlicenses_educatorid_foreign");
);
model.Entity<EducatorLicense>(builder =>
builder.Property(p => p.id)
.ValueGeneratedOnAdd();
builder.HasKey(c => c.id);
);
我得到了那个例外:
我希望它在获取教育者表时也能获得教育者许可表。
我想我可以在业务层做到这一点,通过延迟加载两次访问数据库。
有没有办法让两个表同时连接到外部?
【问题讨论】:
【参考方案1】:您以错误的方式配置外键。以下代码-
builder.HasOne(d => d.EducatorLicense)
.WithMany()
.HasForeignKey(d => d.Id)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("educatorlicenses_educatorid_foreign");
应该是-
builder.HasMany(d => d.EducatorLicense)
.WithOne()
.HasForeignKey(d => d.EducatorId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("educatorlicenses_educatorid_foreign");
那么如果你像这样查询 -
var educatorList = myDbContext.Educators.Include(p=> p.EducatorLicense).ToList();
您将获得Educator
的列表以及他们的EducatorLicense
列表。
提示:
为了更好地反映它是一个集合的事实(因此,关系的Many
结束),您应该将Educator
类中的EducatorLicense
属性重命名为它的复数形式EducatorLicenses
。
【讨论】:
【参考方案2】:尝试用这个替换你的数据库上下文
modelBuilder.Entity<Educator>(entity =>
entity.HasOne(d => d.Educator)
.WithMany(p => p.EducatorLicences)
.HasForeignKey(d => d.EducatorId)
.OnDelete(DeleteBehavior.ClientSetNull);
);
builder.OwnsOne(c => c.Timestamps,
a =>
a.Property(p => p.CreatedAt).HasColumnName("createdAt");
a.Property(p => p.UpdatedAt).HasColumnName("updatedAt");
);
将教育者添加到您的教育者许可中
public class EducatorLicense
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id get; set;
[JsonIgnore] public int EducatorId get; set;
public Educator Educator get; set;
public string LicenseType get; set;
将 Educator 类的 EducatorLicense 重命名为 EducatorLicenses
public List<EducatorLicense> EducatorLicenses get; set;
【讨论】:
以上是关于ef core 如何一次从具有外键的不同表中获取数据? (数据库优先)的主要内容,如果未能解决你的问题,请参考以下文章
休眠。如何将条目添加到具有来自 Hibernate 中 2 个不同表的 2 个外键的表中?
要在 EF Core 中添加没有外键的导航属性,使用 .NET Core Web API 进行 DB-first 迁移