单个表实体框架4.3.1中的多个外键
本文关键字:实体 框架 单个表 | 更新日期: 2023-09-27 18:27:27
我是EF的新手,阅读了一些教程,并在谷歌上搜索了很多天,以找到解决我问题的方法。对不起,我的英语不是最好的,但我想试着把我的问题写出来。
数据模型
从SQL Express数据库创建的我的模型(为了更好地理解收缩版本):
参见图片:
创建示例数据
现在我试着用Demo数据填充我的数据库。我创建了一个Liegenschaft对象并在其中填充数据。显示我的数据树的简单版本(真实版本可以在ObjektEnge=List和Objektenge=List中有许多HAUS对象。
List<Liegenschaft> LL = new List<Liegenschaft>();
for (int i = 0; i < 2; i++)
{
Liegenschaft L = new Liegenschaft()
{
Strasse = "demostreet1",
HausMenge = new List<Haus>(){
new Haus(){
Nummer = 21,
ObjektMenge = new List<Objekt>(){
new Objekt(){
Zimmer = 221,
MieterMenge= new List<Mieter>(){
new Mieter(){
Name="DemoName",
MietzinsMenge= new List<Mietzins>(){
new Mietzins(){
StartDate=System.DateTime.Now,
EndDate=System.DateTime.Now},
new Mietzins(){
StartDate=System.DateTime.Now,
EndDate=System.DateTime.Now}
}
}
}
}
}
}
}
};
LL.Add(L);
}
尝试保存到数据库
foreach (Liegenschaft Lieg in LL)
{
using (var db = new ImmoReportsEntities())
{
db.Liegenschaft.Add(Lieg);
db.SaveChanges();
}
}
问题
我的所有演示数据都可以保存到数据库中,当MietzinsMenge未填充时,所有FK都会自动正确创建!
如果我在这个MietzinsMenge中有数据,则会出现错误:FK_MietzinsObjekt有相同的主键!
信息
我不使用Forms将数据插入这个Tabel的所有数据都来自另一个(外部)DB,我想将其导入我的DB。我如何在我的数据树中导入这个MietZins,并拥有所有这些FK(LiegenschftId、ObjektId、MieterId)。
看起来并不是在为Mietzins对象设置主键值。您需要在尝试保存到数据库之前设置主键值,或者告诉EF主键将由数据库生成。
指定密钥由数据库生成的方式取决于使用的是"代码优先"还是"数据库优先"。在"代码优先"中,它通常默认情况下为整数键类型启用,或者您可以使用DatabaseGeneratedAttribute并设置Identity。对于"数据库优先",使用EF设计器并将密钥属性的StoreGenerated方面设置为Identity。
我使用以下类和代码优先映射重新创建了您的模型,如图所示。(我知道您可能没有使用Code First,但这是我创建具有图中所示所有关系的同一模型的最简单方法。)
public class Mietzins
{
public int Id { get; set; }
public int LiegenschaftId { get; set; }
public int MieterId { get; set; }
public int ObjektId { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public Liegenschaft Liegenschaft { get; set; }
public Mieter Mieter { get; set; }
public Objekt Objekt { get; set; }
}
public class Mieter
{
public int Id { get; set; }
public int LiegenschaftId { get; set; }
public int ObjektId { get; set; }
public string Name { get; set; }
public Liegenschaft Liegenschaft { get; set; }
public ICollection<Mietzins> MietzinsMenge { get; set; }
public Objekt Objekt { get; set; }
}
public class Objekt
{
public int Id { get; set; }
public int LiegenschaftId { get; set; }
public int HausId { get; set; }
public int Zimmer { get; set; }
public Haus Haus { get; set; }
public Liegenschaft Liegenschaft { get; set; }
public ICollection<Mietzins> MietzinsMenge { get; set; }
public ICollection<Mieter> MieterMenge { get; set; }
}
public class Liegenschaft
{
public int Id { get; set; }
public string Strasse { get; set; }
public int UserId { get; set; }
public ICollection<Haus> HausMenge { get; set; }
public ICollection<Mieter> MieterMenge { get; set; }
public ICollection<Mietzins> MietzinsMenge { get; set; }
public ICollection<Objekt> ObjektMenge { get; set; }
}
public class Haus
{
public int Id { get; set; }
public int LiegenschaftId { get; set; }
public int Nummer { get; set; }
public ICollection<Objekt> ObjektMenge { get; set; }
public Liegenschaft Liegenschaft { get; set; }
}
上下文:
public class ImmoReportsEntities : DbContext
{
public DbSet<Liegenschaft> Liegenschaft { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Liegenschaft>()
.HasMany(e => e.HausMenge)
.WithRequired(e => e.Liegenschaft)
.HasForeignKey(e => e.LiegenschaftId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Liegenschaft>()
.HasMany(e => e.MieterMenge)
.WithRequired(e => e.Liegenschaft)
.HasForeignKey(e => e.LiegenschaftId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Liegenschaft>()
.HasMany(e => e.MietzinsMenge)
.WithRequired(e => e.Liegenschaft)
.HasForeignKey(e => e.LiegenschaftId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Liegenschaft>()
.HasMany(e => e.ObjektMenge)
.WithRequired(e => e.Liegenschaft)
.HasForeignKey(e => e.LiegenschaftId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Haus>()
.HasMany(e => e.ObjektMenge)
.WithRequired(e => e.Haus)
.HasForeignKey(e => e.HausId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Objekt>()
.HasMany(e => e.MietzinsMenge)
.WithRequired(e => e.Objekt)
.HasForeignKey(e => e.ObjektId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Objekt>()
.HasMany(e => e.MieterMenge)
.WithRequired(e => e.Objekt)
.HasForeignKey(e => e.ObjektId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Mieter>()
.HasMany(e => e.MietzinsMenge)
.WithRequired(e => e.Mieter)
.HasForeignKey(e => e.MieterId)
.WillCascadeOnDelete(false);
}
}
然后我按照问题中的方式运行了您的代码,它运行得很好。
然后我更改了Mietzins的主键,使其不再是数据库生成的:
public class Mietzins
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public int LiegenschaftId { get; set; }
public int MieterId { get; set; }
public int ObjektId { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public Liegenschaft Liegenschaft { get; set; }
public Mieter Mieter { get; set; }
public Objekt Objekt { get; set; }
}
我再次运行代码,得到以下异常:
未处理的异常:System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。--->System.Data.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。--->System.Data.SqlClient.SqlException:违反PRIMARY KEY约束"PK_Mietzins"。无法在对象"dbo.Mietzins"中插入重复的键。语句已终止。
如果这与您看到的异常不同,请发布您的代码、完整的异常消息和堆栈跟踪,我会再看一眼。