单个表实体框架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)。

单个表实体框架4.3.1中的多个外键

看起来并不是在为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"中插入重复的键。语句已终止。

如果这与您看到的异常不同,请发布您的代码、完整的异常消息和堆栈跟踪,我会再看一眼。