ef core如何一次从不同的外键表中获取数据? (数据库优先)
ef core how to get data from different tables with foreign keys at once? (DB first)
我的项目中有两个 table,“教育者”和“教育者许可证”。
教育者许可证依赖于具有外键的教育者 table。 (数据库优先)
我的数据库中带有 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);
});
}
我得到了那个例外:
我希望它在获得教育者 table 时获得教育者许可 table。
我想我可以在业务层做到这一点,通过延迟加载两次访问数据库。
有没有办法让两个 table 的人同时与对方建立联系?
尝试用这个替换你的数据库上下文
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");
});
将 Educator 添加到您的 EducatorLicense
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; }
}
将 Educatorclass 的 EducatorLicense 重命名为 EducatorLicenses
public List<EducatorLicense> EducatorLicenses { get; set; }
您配置外键的方式有误。以下代码-
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
属性 32=] 的复数形式 EducatorLicenses
.
我的项目中有两个 table,“教育者”和“教育者许可证”。
教育者许可证依赖于具有外键的教育者 table。 (数据库优先)
我的数据库中带有 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);
});
}
我得到了那个例外:
我希望它在获得教育者 table 时获得教育者许可 table。
我想我可以在业务层做到这一点,通过延迟加载两次访问数据库。
有没有办法让两个 table 的人同时与对方建立联系?
尝试用这个替换你的数据库上下文
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");
});
将 Educator 添加到您的 EducatorLicense
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; }
}
将 Educatorclass 的 EducatorLicense 重命名为 EducatorLicenses
public List<EducatorLicense> EducatorLicenses { get; set; }
您配置外键的方式有误。以下代码-
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
属性 32=] 的复数形式 EducatorLicenses
.