JoacimWall
JoacimWall

Reputation: 41

Entity Framework 5 code first self referencing with extra attribute

Hi my problem is that when i run Add-Migration my database model end up like this. FK four times instead of two.

CreateTable(
            "dbo.IntressentIntressent",
            c => new
                {
                    ParentIntressentId = c.Int(nullable: false),
                    ChildIntressentId = c.Int(nullable: false),
                    Aktieantal = c.Int(nullable: false),
                    Agare = c.Boolean(nullable: false),
                    Firmatecknare = c.Boolean(nullable: false),
                    Registreringsanmalan = c.Boolean(nullable: false),
                    FirmatecknareGeneralfullmakt = c.Boolean(nullable: false),
                    Revisor = c.Boolean(nullable: false),
                })
            .PrimaryKey(t => new { t.ParentIntressentId, t.ChildIntressentId })
            .ForeignKey("dbo.Intressent", t => t.ParentIntressentId)
            .ForeignKey("dbo.Intressent", t => t.ChildIntressentId)
            .ForeignKey("dbo.Intressent", t => t.ParentIntressentId)
            .ForeignKey("dbo.Intressent", t => t.ChildIntressentId)
            .Index(t => t.ParentIntressentId)
            .Index(t => t.ChildIntressentId)
            .Index(t => t.ParentIntressentId)
            .Index(t => t.ChildIntressentId);

My classes look like this. if i remove fk statement in onmodelCreating EF will add it for me.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {   
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Entity<Entity.IntressentIntressent>().HasKey(k => new
       {k.ParentIntressentId, k.ChildIntressentId });

       modelBuilder.Entity<Entity.Intressent>().HasMany(c => c.ParentIntressenter)
                   .WithRequired().HasForeignKey(cp => cp.ParentIntressentId);

       modelBuilder.Entity<Entity.Intressent>().HasMany(p => p.ChildIntressenter)
                   .WithRequired().HasForeignKey(cp => cp.ChildIntressentId);

   }

Entitys look like this

public class Intressent
{

    private ObservableCollection<IntressentIntressent> _parentIntressenter;
    public virtual ObservableCollection<IntressentIntressent> ParentIntressenter
    {
         get { return _parentIntressenter ?? (_parentIntressenter = new  
            ObservableCollection<IntressentIntressent>()); }
        set { _parentIntressenter = value; }
    }
}

public class IntressentIntressent
{
    [DisplayName("ParentIntressentId")]
    [Description("ParentIntressentId")]
    [Key, ForeignKey("ParentIntressent")]
    public int ParentIntressentId { get; set; }
    [DisplayName("ChildIntressentId")]
    [Description("ChildIntressentId")]
    [Key, ForeignKey("ChildIntressent")]
    public int ChildIntressentId { get; set; }


    [ForeignKey("ParentIntressent")]
    public Intressent ParentIntressent { get; set; }
    [ForeignKey("ChildIntressent")]
    public Intressent ChildIntressent { get; set; }

    [Required]
    [DisplayName("Aktieantal")]
    [Description("Aktieantal")]
    public int Aktieantal { get; set; }
}

Upvotes: 0

Views: 744

Answers (1)

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364299

You have duplicated the relation. In your IntressentIntressent you have used data annotations to define navigation properties and their related foreign keys. Then you have define fluent mapping for Intressent class but that mapping doesn't reflect those data annotations on opposite side of the relation. That result in defining relations twice. Replace fluent mapping with this:

   modelBuilder.Entity<Entity.Intressent>()
               .HasMany(c => c.ParentIntressenter)
               .WithRequired(i => i.ParentInterssenter)
               .HasForeignKey(cp => cp.ParnetIntressentId);

   modelBuilder.Entity<Entity.Intressent>()
               .HasMany(p => p.ChildIntressenter)
               .WithRequired(i => i.ChildIntressent)
               .HasForeignKey(cp => cp.ChildIntressentId);

By defining opposite in WithRequired you pair those navigation properties to single relation.

Upvotes: 1

Related Questions