0

I am trying to formulate one to one mapping but Entity framework always forming wrong foreign keys. I have tried all possible combinitions for stting up directions using Fluent API. But I have no idea why this is doing so.

My Model heirarchy is :

(Principal Table) Packaging (Dependent Table) FortressPackaging.

Their respective models are

 public class Packaging
 {
    public int PackagingId { get; set; }        

    [Display(Name = "Weight")]
    public double? Weight { get; set; }
    .................................
    ..........................

    //navigation property....
    public virtual FortressPackaging FortressPackaging { get; set; }
 }

 public class FortressPackaging
 {
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FortressPackagingId { get; set; }

    [StringLength(2)]
    [Index("IX_FortressPackaging_FortressKey", 1, IsUnique = true)]
    public string FortressKey { get; set; }

    [Index("IX_FortressPackaging_PackagingId", 2, IsUnique = true)]
    public int PackagingId { get; set; } // Foreign key to Packaging ( Principal Table)

    public virtual Packaging Packaging { get; set; }
 }

I followed following Fluent API

    modelBuilder.Entity<FortressPackaging>()
                .HasKey(Pr => Pr.FortressPackagingId)
                .Property(Pr => Pr.FortressPackagingId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    modelBuilder.Entity<FortressPackaging>()
                .HasRequired(Pr => Pr.Packaging);    

and when I performed migration, I got the following script.

public override void Up()
        {
            CreateTable(
                "dbo.FortressPackaging",
                c => new
                    {
                        FortressPackagingId = c.Int(nullable: false, identity: true),
                        FortressKey = c.String(maxLength: 2),
                        PackagingId = c.Int(),
                    })
                .PrimaryKey(t => t.FortressPackagingId)
                .ForeignKey("dbo.Packaging", t => t.FortressPackagingId) // SHOULD BE t=>t.PackagingId instead of t.FortressPackagingId

                .Index(t => t.FortressPackagingId)
                .Index(t => t.FortressKey, unique: true, name: "IX_FortressPackaging_FortressKey")
                .Index(t => t.PackagingId, unique: true, name: "IX_FortressPackaging_PackagingId");                
        }

Here I don't know Why it is mapping FortressPackagingId as foriegn key to the FortressPackaging table while it is already a mapped as primary key which I explicitly marked while model creation.

I want to have following relation.

Packaging may or may not have a FortressPackaging while FortressPackaging always have a corresponding packaging. ( so One->0->One mapping )

How can I have correctly mapped foreign key

Edit : After removing Foreign Key Property from FortressPackaging.

    public class FortressPackaging
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int FortressPackagingId { get; set; }

        [StringLength(2)]
        [Index("IX_FortressPackaging_FortressKey", 1, IsUnique = true)]
        public string FortressKey { get; set; }

        [Index("IX_FortressPackaging_PackagingId", 2, IsUnique = true)]
        public int PackagingId { get; set; }
        public Packaging Packaging { get; set; }
    }

Created migration again with the same contents as before..

public override void Up()
        {
            CreateTable(
                "dbo.FortressPackaging",
                c => new
                    {
                        FortressPackagingId = c.Int(nullable: false, identity: true),
                        FortressKey = c.String(maxLength: 2),
                        PackagingId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.FortressPackagingId)
                .ForeignKey("dbo.Packaging", t => t.FortressPackagingId)
                .Index(t => t.FortressPackagingId)
                .Index(t => t.FortressKey, unique: true, name: "IX_FortressPackaging_FortressKey")
                .Index(t => t.PackagingId, unique: true, name: "IX_FortressPackaging_PackagingId");

        }

Followed : https://stackoverflow.com/a/26012062/273330

Fluent API :

modelBuilder.Entity<FortressPackaging>()
                        .HasRequired(Pr => Pr.Packaging)
                        .WithMany()
                        .HasForeignKey(Pr=>Pr.PackagingId)
                        .WillCascadeOnDelete(false);

Migration Script created in result of above fluent api :

public override void Up()
        {
            CreateTable(
                "dbo.FortressPackaging",
                c => new
                    {
                        FortressPackagingId = c.Int(nullable: false, identity: true),
                        FortressKey = c.String(maxLength: 2),
                        PackagingId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.FortressPackagingId)
                .ForeignKey("dbo.Packaging", t => t.PackagingId)
                .Index(t => t.FortressKey, unique: true, name: "IX_FortressPackaging_FortressKey")
                .Index(t => t.PackagingId, unique: true, name: "IX_FortressPackaging_PackagingId");

            AddColumn("dbo.Packaging", "FortressPackaging_FortressPackagingId", c => c.Int());
            CreateIndex("dbo.Packaging", "FortressPackaging_FortressPackagingId");
            AddForeignKey("dbo.Packaging", "FortressPackaging_FortressPackagingId", "dbo.FortressPackaging", "FortressPackagingId");
        }

I don't know why it is creating totally new columns inside Packaging table.

Community
  • 1
  • 1
Usman
  • 2,742
  • 4
  • 44
  • 82
  • If Packaging is required in ForestPackaging, then PackagingId should not be nullable. I would also pick annotations or fluent - mixing can cause side effects. Finally, see this for a similar config: http://stackoverflow.com/questions/18240362/one-to-one-optional-relationship-using-entity-framework-code-first – Steve Greene May 03 '16 at 13:10
  • Sorry, it was required as you said. Now I followed what is being described on your provided link. I got updated Script. Could you have a look. – Usman May 03 '16 at 15:17
  • If I follow the idea described over http://stackoverflow.com/a/26012062/273330 This would make the PackagingId as foreignkey to Packaging in FortressPackaging, but it would result in creation of two more columns inside the packaging table, which I really don't required. Look on edit again. – Usman May 03 '16 at 15:32

0 Answers0