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.