17

I wonder if there is any chance to change name of foreign key constraint generated by Entity Framework when using code first.

I have two entities - User and Group - with many-to-many relationship so there is an association table GroupUser. Unfortunately, auto-generated foreign key constraints are named FK_dbo.GroupUser_dbo.User_User_UserId and FK_dbo.GroupUser_dbo.Group_Group_GroupId.

I would like to have foreign key constraints called like FK_GroupUser_UserId and FK_GroupUser_GroupId. That looks much cleaner to me.

Slauma
  • 175,098
  • 59
  • 401
  • 420
MrHenkey
  • 183
  • 1
  • 1
  • 6
  • Try [how-to-customize-foreign-key-column...][1] [1]: http://stackoverflow.com/questions/5700645/how-to-customize-foreign-key-column-name-using-entity-framework-code-first – Nilesh Jul 29 '13 at 14:23
  • That is only how to set custom column name not foreign key name. There is plenty of questions and answers on customizing foreign key column name but I didn't find any on customizing foreign name itself. – MrHenkey Jul 29 '13 at 14:28

2 Answers2

10

It's not possible to customize the foreign key constraint name with data annotations or DbModelBuilder Fluent API. However, you can control the name with code-based migrations.

  • First option: When the tables get created via migrations:

    The migration code that gets automatically generated for the join table would look like this:

    public partial class MyMigration : DbMigration
    {
        public override void Up()
        {
            CreateTable("GroupUser",
                c => new
                {
                    UserId = c.Int(nullable: false),
                    GroupId = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.UserId, t.GroupId })
            .ForeignKey("User", t => t.UserId, cascadeDelete: true)
            .ForeignKey("Group", t => t.GroupId, cascadeDelete: true)
            .Index(t => t.UserId)
            .Index(t => t.GroupId);
    
            // ...
        }
    }
    

    Here you can modify the two ForeignKey method calls to set a custom constraint name before you call update-database:

            .ForeignKey("User", t => t.UserId, cascadeDelete: true,
                name: "FK_GroupUser_UserId")
            .ForeignKey("Group", t => t.GroupId, cascadeDelete: true,
                name: "FK_GroupUser_GroupId")
    
  • Second option: When the tables already exist you can drop the constraint and add a new renamed one in a migration:

    public partial class MyMigration : DbMigration
    {
        public override void Up()
        {
            DropForeignKey("UserGroup", "UserId", "User");
            DropForeignKey("UserGroup", "GroupId", "Group");
    
            AddForeignKey("UserGroup", "UserId", "User",
                name: "FK_GroupUser_UserId");
            AddForeignKey("UserGroup", "GroupId", "Group",
                name: "FK_GroupUser_GroupId")
    
            // ...
        }
    }
    
Slauma
  • 175,098
  • 59
  • 401
  • 420
  • 1
    How do I drop the foreign key if its already got a custom name, as the script generated uses the field names and so it doesnt get dropped because it doesnt enter the if statement – Alan Ball Jul 20 '16 at 11:30
  • 1
    @AlanBall this is late, but to drop a foreign key with custom name, use DropForeignKey("TableName", "ForeignKeyName") – kitkatsim Feb 21 '20 at 22:00
3

You can implement a custom sql generator class derived from SqlServerMigrationSqlGenerator from System.Data.Entity.SqlServer

For more datail plese see the answer

Community
  • 1
  • 1
Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116