简体   繁体   English

具有链接表的实体框架代码优先迁移问题

[英]Entity Framework Code First Migration issue with linking tables

I'm using EF 5.0 code first, using automatic migrations via the PM console. 我首先使用EF 5.0代码,并通过PM控制台进行自动迁移。

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. 我有2类用户和站点。

InitialCreate Migration InitialCreate迁移

This created a link table called "UserSites" by convention. 按照惯例,这创建了一个称为“ UserSites”的链接表。

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. 这将删除UserSites链接表并创建一个SiteUsers链接表。

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! 我更改了dbcontext的名称空间,仅此而已! 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 ? 您是否在DbContext任何更改? How you declare Sites and Users properties in your classes? 如何在类中声明SitesUsers属性?

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 然后删除您的第4个迁移,然后尝试再次添加

If you remove your migration code, you'll catch navigation errors like foreign keys problem, incorrect table name, etc. 如果删除迁移代码,则会捕获导航错误,例如外键问题,错误的表名等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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