实体框架6表拆分生成无效的迁移

时间:2018-07-16 10:29:52

标签: c# entity-framework

我们在项目中使用了带有代码过滤功能的EF表拆分,因此我们可以提高数据库的性能(其中一个模型包含127列)。如果将拆分与延迟加载或查询一起使用,则拆分工作正常,但是当我们要以表的形式访问拆分的模型(dbContext.UserSettings.FindAsync(userId))时遇到问题。将模型作为表添加到DbContext时,我们将获得无效迁移。

我不确定是否遇到错误或只是配置错误。我创建了一个最小的示例来重现该错误。

条件

  • 该模型必须至少拆分为2个拆分模型
  • 该模型必须与另一个模型至少包含2个关系

问题

没有将拆分的模型定义为表的DbContext会生成正确的迁移。这些关系是正确的,并且所有模型都存在并且可以正常工作。当我们为拆分后的模型添加表定义时,EF会生成一个迁移,该迁移交换两个零对多关系的列并破坏数据库和代码。

RenameColumn(table: "dbo.Users", name: "ImageLargeId", newName: "__mig_tmp__0");
RenameColumn(table: "dbo.Users", name: "ImageSmallId", newName: "ImageLargeId");
RenameColumn(table: "dbo.Users", name: "__mig_tmp__0", newName: "ImageSmallId");
RenameIndex(table: "dbo.Users", name: "IX_ImageLargeId", newName: "__mig_tmp__0");
RenameIndex(table: "dbo.Users", name: "IX_ImageSmallId", newName: "IX_ImageLargeId");
RenameIndex(table: "dbo.Users", name: "__mig_tmp__0", newName: "IX_ImageSmallId");

这当然会破坏我们的数据库和代码。我们尝试了不同的方法,但它总是会导致这种无效的迁移。

代码

public class BugContext : DbContext
{
    public virtual DbSet<Image> Images { get; set; }
    public virtual DbSet<User> Users { get; set; }

    // BUG: Enable/disable this part will generate a invalid migration file
    //public virtual DbSet<UserSettings> UserSettings { get; set; }
    //public virtual DbSet<UserRights> UserRights { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().ToTable("Users");
        modelBuilder.Entity<UserSettings>().ToTable("Users");
        modelBuilder.Entity<UserRights>().ToTable("Users");

        modelBuilder.Entity<User>().HasOptional(user => user.ImageSmall).WithMany(image => image.User_ImageSmalls);
        modelBuilder.Entity<User>().HasOptional(user => user.ImageLarge).WithMany(image => image.User_ImageLarges);

        modelBuilder.Entity<User>().HasRequired(user => user.Settings).WithRequiredPrincipal(userSettings => userSettings.User);
        modelBuilder.Entity<User>().HasRequired(user => user.Rights).WithRequiredPrincipal(userRights => userRights.User);
    }
}

public class Image
{
    [Key]
    public Guid Id { get; set; }

    public virtual ICollection<User> User_ImageSmalls { get; set; }
    public virtual ICollection<User> User_ImageLarges { get; set; }
}

public class User
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    [MaxLength(256)]
    public string Name { get; set; }

    public Guid? ImageSmallId { get; set; }
    public virtual Image ImageSmall { get; set; }

    public Guid? ImageLargeId { get; set; }
    public virtual Image ImageLarge { get; set; }

    public virtual UserSettings Settings { get; set; }
    public virtual UserRights Rights { get; set; }
}

public class UserSettings
{
    [Key]
    public Guid Id { get; set; }

    [ForeignKey(nameof(Id))]
    public virtual User User { get; set; }

    public bool DarkTheme { get; set; }
}

public class UserRights
{
    [Key]
    public Guid Id { get; set; }

    [ForeignKey(nameof(Id))]
    public virtual User User { get; set; }

    public bool Admin { get; set; }
}

复制步骤

  1. 添加迁移:“添加迁移初始化”
  2. 更新数据库:“ update-database”
  3. 取消注释以下代码“ public virtual DbSet UserSettings {get; set;}”和“ public virtual DbSet UserRights {get; set;}”
  4. 添加迁移:“添加迁移错误”

0 个答案:

没有答案