none
Entity Framework 6 inverting column order for composite foreign keys RRS feed

  • Question

  • I'm getting this error:

    (15,10) : error 3015: Problem in mapping fragments starting at lines 6, 15: Foreign key constraint 'Beta_Alpha' from table Beta (Alpha_2, Alpha_1) to table Alpha (Alpha_1, Alpha_2):: Insufficient mapping: Foreign key must be mapped to some AssociationSet or EntitySets participating in a foreign key association on the conceptual side.

    The key information is that the composite foreign key in Beta (Alpha_2, Alpha_1) has the columns inverted, with Alpha_2 first and Alpha_1 second. This appears to be a bug in Entity Framework.

    Here are the entities:

    public class Alpha
    {
        [Key, Column(Order = 1)]
        public string Alpha_1 { get; set; }
        [Key, Column(Order = 2)]
        public string Alpha_2 { get; set; }
    }
    
    public class Beta
    {
        [Key, Column(Order = 1)]
        public string Beta_1 { get; set; }
        [Key, Column(Order = 2)]
        public string Alpha_2 { get; set; }
        [Required]
        public string Alpha_1 { get; set; }
    
        [ForeignKey("Alpha_1, Alpha_2")]
        public virtual Alpha Alpha { get; set; }
    }

    Note that the ForeignKey attribute in Beta correctly lists Alpha_1 first.

    Here is the Migration that's generated:

    public partial class Test : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Betas",
                c => new
                    {
                        Beta_1 = c.String(nullable: false, maxLength: 128),
                        Alpha_2 = c.String(nullable: false, maxLength: 128),
                        Alpha_1 = c.String(nullable: false, maxLength: 128),
                    })
                .PrimaryKey(t => new { t.Beta_1, t.Alpha_2 })
                .ForeignKey("dbo.Alphas", t => new { t.Alpha_2, t.Alpha_1 }, cascadeDelete: true)
                .Index(t => new { t.Alpha_2, t.Alpha_1 });
    
            CreateTable(
                "dbo.Alphas",
                c => new
                    {
                        Alpha_1 = c.String(nullable: false, maxLength: 128),
                        Alpha_2 = c.String(nullable: false, maxLength: 128),
                    })
                .PrimaryKey(t => new { t.Alpha_1, t.Alpha_2 });
    
        }
    
        public override void Down()
        {
            DropForeignKey("dbo.Betas", new[] { "Alpha_2", "Alpha_1" }, "dbo.Alphas");
            DropIndex("dbo.Betas", new[] { "Alpha_2", "Alpha_1" });
            DropTable("dbo.Alphas");
            DropTable("dbo.Betas");
        }
    }

    Even if I manually update the Migration, I still get the error because the internal model itself is inverting the columns.

    The bug appears to be related to the fact that Alpha_2 is also part of Beta's composite primary key.

    Cross-posted at Stack Overflow


    • Edited by Nihimon Thursday, July 23, 2015 5:35 PM
    Thursday, July 23, 2015 5:32 PM

Answers

  • Workaround provided at Stack Overflow:

    http://stackoverflow.com/questions/31594304/entity-framework-6-inverting-column-order-for-composite-foreign-keys/31616797#31616797

    Monday, July 27, 2015 2:05 PM

All replies

  • Thanks for the link, _Omar.

    I removed the ForeignKey("Alpha_1, Alpha_2") Attribute and added the following to my DbContext:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    	base.OnModelCreating(modelBuilder);
    	modelBuilder.Entity<Beta>()
    		.HasRequired(p => p.Alpha)
    		.WithMany()
    		.HasForeignKey(p => new { p.Alpha_1, p.Alpha_2 });
    }

    However, I'm still getting the following in my Migration:

    CreateTable(
        "dbo.Betas",
        c => new
            {
                Beta_1 = c.String(nullable: false, maxLength: 128),
                Alpha_2 = c.String(nullable: false, maxLength: 128),
                Alpha_1 = c.String(nullable: false, maxLength: 128),
            })
        .PrimaryKey(t => new { t.Beta_1, t.Alpha_2 })
        .ForeignKey("dbo.Alphas", t => new { t.Alpha_2, t.Alpha_1 }, cascadeDelete: true)
        .Index(t => new { t.Alpha_2, t.Alpha_1 });

    As you can see, it's still inverting the columns.

    The other suggestion at that link was to specify the Column Order with an Attribute, like this:

    [ForeignKey("PatientContact"), Column(Order = 0)]
    public int Person_ID{ get; set; }
    [ForeignKey("PatientContact"), Column(Order = 1)]
    public int Patient_ID{ get; set; }

    This is an obvious problem, though, because I'm already specifying the Column Order for Alpha_2's participation in Beta's Primary Key, and that Order is different than it needs to be for its participation in the Foreign Key to Alpha.

    I would need to do something like this:

    public class Beta
    {
    	[Key, Column(Order = 1)]
    	public string Beta_1 { get; set; }
    	[Key, Column(Order = 2), ForeignKey("Alpha"), Column(Order = 1)]
    	public string Alpha_2 { get; set; }
    	[Required, ForeignKey("Alpha"), Column(Order = 2)]
    	public string Alpha_1 { get; set; }
    
    	public virtual Alpha Alpha { get; set; }
    }

    But I can't because I can only use the Column attribute once.

    Friday, July 24, 2015 1:39 PM
  • Workaround provided at Stack Overflow:

    http://stackoverflow.com/questions/31594304/entity-framework-6-inverting-column-order-for-composite-foreign-keys/31616797#31616797

    Monday, July 27, 2015 2:05 PM