简体   繁体   中英

Entity Framework Code First Migration issue with linking tables

I'm using EF 5.0 code first, using automatic migrations via the PM console.

I'm attempting to apply a 4th migration to a project and the convention based naming of my linking tables is causing them to be dropped and recreated with a different name. This has not occurred during any of the previous migrations.

Example :

I have 2 classes User and Site.

InitialCreate Migration

This created a link table called "UserSites" by convention.

CreateTable(
           "dbo.UserSites",
            c => new
                {
                    User_Id = c.Guid(nullable: false),
                    Site_Id = c.Guid(nullable: false),
                })
            .PrimaryKey(t => new { t.User_Id, t.Site_Id })
            .ForeignKey("dbo.Users", t => t.User_Id, cascadeDelete: true)
            .ForeignKey("dbo.Sites", t => t.Site_Id, cascadeDelete: true)
            .Index(t => t.User_Id)
            .Index(t => t.Site_Id);

Everything works well.

Skip to today :

4th Migration

This drops the UserSites link table and creates a SiteUsers link table.

Obviously not ideal!

public override void Up()
    {
        DropForeignKey("dbo.UserSites", "User_Id", "dbo.Users");
        DropForeignKey("dbo.UserSites", "Site_Id", "dbo.Sites");
        DropIndex("dbo.UserSites", new[] { "User_Id" });
        DropIndex("dbo.UserSites", new[] { "Site_Id" });


        CreateTable(
            "dbo.SiteUsers",
            c => new
                {
                    Site_Id = c.Guid(nullable: false),
                    User_Id = c.Guid(nullable: false),
                })
            .PrimaryKey(t => new { t.Site_Id, t.User_Id })
            .ForeignKey("dbo.Sites", t => t.Site_Id, cascadeDelete: true)
            .ForeignKey("dbo.Users", t => t.User_Id, cascadeDelete: true)
            .Index(t => t.Site_Id)
            .Index(t => t.User_Id);

        DropTable("dbo.UserSites");

I'm at a loss to explain this.

Neither class has changed since the first implementation... and I presume if I apply this I will suffer data loss.

So to the question(s) :

  1. Can I just remove this code from the migration script and continue using my existing structure?

  2. Is there a gotcha that I don't know about that might have caused this?

Any/all assistance much appreciated!

Edit:

I have simply defined the classes as below and allowed the model to be built by convention. I have changed the namespace of the dbcontext, but that is all! Colour me bewildered.

public class User
{
   public virtual ICollection<Site> Sites { get; set; }
}

public class Site
{
    public virtual ICollection<User> Users { get; set; }
}

It's a strange situation. Did you change anything in your DbContext ? How you declare Sites and Users properties in your classes?

I think you should explicit add many-to-many relationship to your db context, like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<User>()
                .HasMany<Sites>(u => u.Sites)
                .WithMany(e => e.Users)
                .Map(
                    m =>
                        {
                            m.MapLeftKey("User_Id");
                            m.MapRightKey("Site_Id");
                            m.ToTable("UserSites");
                        });

    //for prevent error 'The referential relationship will result in a cyclical reference that is not allowed'
    modelBuilder.Entity<Sites>()
                .HasRequired(s => s.User)
                .WithMany()
                .WillCascadeOnDelete(false);
}

Then remove your 4th migration and try to add it again

If you remove your migration code, you'll catch navigation errors like foreign keys problem, incorrect table name, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM