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

时间:2012-03-09 15:05:17

标签: c# entity-framework sql-server-express foreign-key-relationship

我是EF的新手,已经阅读了一些教程和谷歌搜索了很多天,以找到解决我的问题的方法。对不起,我的英语不是最好的,但我想尝试制定我的问题。

数据模型

我的模型是从SQL Express数据库创建的(缩小版本以便更好地理解):

See Image

创建样本数据

现在我尝试用演示数据填充我的数据库。我创建了一个Liegenschaft对象并在其中填充数据。显示我的数据树的简单版本(真实版本可以在ObjektMenge = List中包含许多HAUS对象,也可以用于ObjektMenge = List。

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);
        }

尝试保存到DB

foreach (Liegenschaft Lieg in LL)
{
    using (var db = new ImmoReportsEntities())
    {
        db.Liegenschaft.Add(Lieg);
        db.SaveChanges();
    }  
 }

问题

我的所有演示数据都可以保存到数据库中,并且当MietzinsMenge未填充时,所有FK都会自动生成!

如果我在此MietzinsMenge中有数据会出错:FK_Mietzins_Objekt具有相同的主键!

信息

我不使用Forms将数据插入此Tabel的所有数据来自另一个(外部)数据库,我想将其导入我的数据库。我如何在我的数据树中导入这个MietZins并拥有所有这些FK(LiegenschftId,ObjektId,MieterId)。

1 个答案:

答案 0 :(得分:0)

看起来您没有为Mietzins对象设置主键值。您需要在尝试保存到数据库之前设置主键值,或者告诉EF主数据库将由数据库生成。

如何指定数据库生成密钥取决于您使用的是Code First还是Database First。在Code First中,默认情况下它通常用于整数键类型,或者您可以使用DatabaseGeneratedAttribute并设置Identity。对于Database First,您使用EF Designer并将key属性的StoreGenerated方面设置为Identity。

我使用以下类和Code First映射重新创建了模型,如图所示。 (我知道你可能没有使用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: 更新条目时发生错误。 有关详细信息,请参阅内部异常 ---&GT; System.Data.UpdateException:更新条目时发生错误。 有关详细信息,请参阅内部异常 ---&GT; System.Data.SqlClient.SqlException:违反PRIMARY KEY约束'PK_Mietzins'。无法在对象'dbo.Mietzins'中插入重复键。 声明已经终止。

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