How do I add an additional column to the __Migrati

2020-02-12 22:11发布

问题:

Per Customizing the Migrations History Table, I should be able to add a column, however I'm not able to find any examples on how to actually add the new column.

I'm mostly confused about where to put the actual property and how to configure it to the existing __MigrationHistory table. From the documentation, I can customize the table configuration like so..

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<HistoryRow>().ToTable(tableName: "MigrationHistory", schemaName: "admin");
    modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID");
}

...but I can't modify the HistoryRow entity.

Am I supposed to add a new derived type based on the HistoryRow entity?

回答1:

First you need to create a new class for your history row entity. For example:

public sealed class MyHistoryRow : HistoryRow
{
    //We will just add a text column
    public string MyColumn { get; set; }
}

Next we need a context, same as we do for normal EF operations, this time however we inherit from HistoryContext:

public class MyHistoryContext : HistoryContext
{
    //We have to 'new' this as we are overriding the DbSet type
    public new DbSet<MyHistoryRow> History { get; set; }

    public MyHistoryContext(DbConnection dbConnection, string defaultSchema)
        : base(dbConnection, defaultSchema)
    {
    }

    //This part isn't needed but shows what you can do
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Rename the table and put it in a different schema. Our new table
        //will be called 'admin.MigrationHistory'
        modelBuilder.Entity<MyHistoryRow>().ToTable(tableName: "MigrationHistory", schemaName: "admin");

        //Rename one of the columns for fun
        modelBuilder.Entity<MyHistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID");
    }
} 

Now to wire them up, we need to configure it, so first we set up the configuration:

public class MyConfiguration : DbConfiguration
{
    public MyConfiguration()
    {
        //Set our new history context to be the one that gets used
        this.SetHistoryContext("System.Data.SqlClient",
            (connection, defaultSchema) => new MyHistoryContext(connection, defaultSchema)); 
    }
}

And finally, make the configuration apply by modifying our web.config: (you will have to fill in your own namespace and application assembly:

<entityFramework codeConfigurationType="Namespace.MyConfiguration, ApplicationAssembly">
    ...snipped...
</entityFramework>

A side effect of doing this is that if/when you enable migrations, you need to explicitly state the context you are working with. This is obviously because you now have two context types in your assembly (unless you split them out.) So you now need to run a command like this:

enable-migrations -ContextTypeName Namespace.YourContextClass