如何使用Entity Framework Core自定义迁移历史记录表

时间:2019-03-25 16:32:41

标签: entity-framework-core ef-migrations entity-framework-core-migrations

我正在用新的API设置Entity Framework Core,以部署到Entity Framework 4.6应用程序使用的现有SQL Server数据库。有一个由其他应用程序共享的“迁移历史记录”表,并且其中每个字段都需要填充2个字段:ContextKey和Model。 Entity Framework Core没有上下文密钥,也没有将模型保存到“迁移历史记录”表中。

我已经创建了一个HistoryRepository:SqlServerHistoryRepository并配置了Entity Framework Core来使用它,但是ConfigureTable方法仅允许您创建其他列,但是在插入自定义数据时实际上并未填充每个记录。为该列提供默认值不是解决方案。

public class HistoryRepository : SqlServerHistoryRepository
{
    public HistoryRepository(HistoryRepositoryDependencies dependencies)
        : base(dependencies)
    {
    }
    protected override void ConfigureTable(EntityTypeBuilder<HistoryRow> history)
    {
        base.ConfigureTable(history);
        history.Property<string>("ContextKey")
            .HasMaxLength(300);
        history.Property<byte[]>("Model");
    }
}

 services.AddDbContext<MDSContext>(options =>
     options.UseLazyLoadingProxies()
            .UseSqlServer(
                 connectionString,
                 x => x.MigrationsHistoryTable("__MigrationHistory")).ReplaceService<Microsoft.EntityFrameworkCore.Migrations.IHistoryRepository, Burkhart.CoreServices.IncomingOrders.Core.Models.Base.HistoryRepository>()
 );

我应该能够动态地为ContextKey和Model提供自定义值

1 个答案:

答案 0 :(得分:0)

我到处都在寻找解决方案,但是它们都向您展示了如何添加列和设置默认值,但没有展示如何动态设置值。我最终在GitHub上挖掘了该解决方案的ASP.NET Entity Framework Core源代码,以便与其他所有人共享它,因为我知道还有其他人正在寻找此信息:

只需覆盖HistoryRepository上的GetInsertScript方法并插入您的自定义值。这是完整的解决方案:

public class HistoryRepository : SqlServerHistoryRepository
{
    public HistoryRepository(HistoryRepositoryDependencies dependencies)
        : base(dependencies)
    {
    }
    protected override void ConfigureTable(EntityTypeBuilder<HistoryRow> history)
    {
        base.ConfigureTable(history);
        history.Property<string>("ContextKey")
            .HasMaxLength(300);
        history.Property<byte[]>("Model");
    }
    public override string GetInsertScript(HistoryRow row)
    {
        var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string));
        return new StringBuilder().Append("INSERT INTO ")
            .Append(SqlGenerationHelper.DelimitIdentifier(TableName, TableSchema))
            .Append(" (")
            .Append(SqlGenerationHelper.DelimitIdentifier(MigrationIdColumnName))
            .Append(", ")
            .Append(SqlGenerationHelper.DelimitIdentifier(ProductVersionColumnName))
            .Append(", [ContextKey], [Model])")
            .Append("VALUES (")
            .Append(stringTypeMapping.GenerateSqlLiteral(row.MigrationId))
            .Append(", ")
            .Append(stringTypeMapping.GenerateSqlLiteral(row.ProductVersion))
            .Append($", '{ContextConstants.ContextName}.{ContextConstants.ContextSchemaName}', 0x)")
            .AppendLine(SqlGenerationHelper.StatementTerminator)
            .ToString();
    }
}

这里是github上源代码的链接: https://github.com/aspnet/EntityFrameworkCore/blob/master/src/EFCore.Relational/Migrations/HistoryRepository.cs