EF Code First:迁移删除所需的列并添加不需要的列

时间:2013-04-22 09:55:09

标签: ef-code-first entity-framework-5

注意:这里有一个“更好”的问题迭代:

EF Code First migrations: Table Per Hierarchy Bug


我试图找出首先采用Table Per Hierarchy结构获取现有数据库和覆盖实体框架代码的确切步骤。但无论我做什么,最终结果迁移都是“错误的”。

以下是示例数据库,确切的步骤和输出。

现有数据库结构

CREATE TABLE [dbo].[Categories](
    [Id] [int] IDENTITY(1,1) NOT NULL Primary Key,
    [Name] [nvarchar](100) NOT NULL, 
 ) 
GO
CREATE TABLE [dbo].[A](
    [Id] [int] IDENTITY(1,1) NOT NULL Primary Key,
    [Discriminator] [nvarchar](20) NOT NULL,
    [Description] [nvarchar](100) NOT NULL,
    [CategoryId] [int] NULL
)GO
ALTER TABLE [dbo].[A]  
WITH CHECK ADD  CONSTRAINT [FK_dbo.A_dbo.Categories_CategoryId] 
FOREIGN KEY([CategoryId])
REFERENCES [dbo].[Categories] ([Id])
GO
ALTER TABLE [dbo].[A] 
CHECK CONSTRAINT [FK_dbo.A_dbo.Categories_CategoryId]
GO

“逆向工程师代码优先”生成以下内容:

 public partial class EntityContext : DbContext {
        static EntityContext() {
            Database.SetInitializer<EntityContext>(null);
        }

        public EntityContext()
            : base("Name=Test47Context") {
        }

        public DbSet<A> A { get; set; }
        public DbSet<Category> Categories { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            modelBuilder.Configurations.Add(new AMap());
            modelBuilder.Configurations.Add(new CategoryMap());
        }
    }

    public partial class A {
        public int Id { get; set; }
        public string Discriminator { get; set; }
        public string Description { get; set; }
        public Nullable<int> CategoryId { get; set; }
        public virtual Category Category { get; set; }
    }

    public partial class Category {
        public Category() {
            this.A = new List<A>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<A> A { get; set; }
    }

    public class AMap : EntityTypeConfiguration<A> {
        public AMap() {
            // Primary Key
            this.HasKey(t => t.Id);

            // Properties
            this.Property(t => t.Discriminator)
                .IsRequired()
                .HasMaxLength(20);

            this.Property(t => t.Description)
                .IsRequired()
                .HasMaxLength(100);

            // Table & Column Mappings
            this.ToTable("A");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.Discriminator).HasColumnName("Discriminator");
            this.Property(t => t.Description).HasColumnName("Description");
            this.Property(t => t.CategoryId).HasColumnName("CategoryId");

            // Relationships
            this.HasOptional(t => t.Category)
                .WithMany(t => t.A)
                .HasForeignKey(d => d.CategoryId);

        }
    }

    public class CategoryMap : EntityTypeConfiguration<Category> {
        public CategoryMap() {
            // Primary Key
            this.HasKey(t => t.Id);

            // Properties
            this.Property(t => t.Name)
                .IsRequired()
                .HasMaxLength(100);

            // Table & Column Mappings
            this.ToTable("Categories");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.Name).HasColumnName("Name");
        }
    }

通过

实施TPH
  • Derived.cs
  • 添加A.cs个继承
  • CategoryCategoryId属性从A.cs移至Derived.cs
  • Discriminator
  • 删除A.cs媒体资源
  • AMap.cs移除DiscriminatorCategoryIdCategory外键映射。
  • 将TPH映射添加到OnModelCreating

    public partial class EntityContext : DbContext {
        static EntityContext() {
            Database.SetInitializer<EntityContext>(null);
        }
    
        public EntityContext()
            : base("Name=Test47Context") {
        }
    
        public DbSet<A> A { get; set; }
        public DbSet<Category> Categories { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            modelBuilder.Configurations.Add(new AMap());
            modelBuilder.Configurations.Add(new CategoryMap());
    
            modelBuilder.Entity<A>()
                .Map<Derived>(x => x.Requires("Discriminator").HasValue("Derived"));
        }
    }
    
    public partial class A {
        public int Id { get; set; }
        public string Description { get; set; }
    }
    
    public class Derived : A {
        public Nullable<int> CategoryId { get; set; }
        public virtual Category Category { get; set; }
    }
    
    public partial class Category {
        public Category() {
            this.A = new List<A>();
        }
    
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<A> A { get; set; }
    }
    
    public class AMap : EntityTypeConfiguration<A> {
        public AMap() {
            // Primary Key
            this.HasKey(t => t.Id);
    
            this.Property(t => t.Description)
                .IsRequired()
                .HasMaxLength(100);
    
            // Table & Column Mappings
            this.ToTable("A");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.Description).HasColumnName("Description");
    
        }
    }
    
    public class CategoryMap : EntityTypeConfiguration<Category> {
        public CategoryMap() {
            // Primary Key
            this.HasKey(t => t.Id);
    
            // Properties
            this.Property(t => t.Name)
                .IsRequired()
                .HasMaxLength(100);
    
            // Table & Column Mappings
            this.ToTable("Categories");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.Name).HasColumnName("Name");
        }
    }
    

“添加迁移TPH”生成以下内容

public partial class TPH : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.A", "Category_Id", c => c.Int());
        AddForeignKey("dbo.A", "Category_Id", "dbo.Categories", "Id");
        CreateIndex("dbo.A", "Category_Id");
        DropColumn("dbo.A", "Discriminator");
    }

    public override void Down()
    {
        AddColumn("dbo.A", "Discriminator", c => c.String(nullable: false, maxLength: 20));
        DropIndex("dbo.A", new[] { "Category_Id" });
        DropForeignKey("dbo.A", "Category_Id", "dbo.Categories");
        DropColumn("dbo.A", "Category_Id");
    }
}
  • 为什么会删除Discriminator列而不是仅将其更改为nvarchar(128)
  • 为什么不只使用现有的CategoryId列而不是添加Category_Id

0 个答案:

没有答案