EF 6 - 将自定义字段/数据添加到__MigrationHistory表

时间:2016-07-27 18:14:25

标签: entity-framework-6 ef-migrations

基于这两个链接

Customizing the Migrations History Table (EF6 onwards)

Add an Additional Column to MigrationHistory table

我能够在SQL中自定义我的Entity Framework 6 __MigrationHistory表。我需要添加一个名为 SoftwareVersion 的新列。我有 AutomaticMigrationsEnabled ,每当实体发生变化时,都会自动生成新的迁移。然后,我在 DbMigrator 类上调用更新方法,数据库将更新,并在__MigrationHistory表中创建新记录。 SoftwareVersion 列就在那里(显然为空),这是一个名为 Discriminator 的新列,其值为" HistoryRow"。

现在我已经成功定制了__MigrationHistory表,但我不知道如何将数据实际插入到 SoftwareVersion 字段中!我尝试使用 HistoryContext 来更新记录,如下所示:

using(TitanHistoryContext context = new TitanHistoryContext(dbConnection, defaultSchema))
{
  TitanHistoryRow historyRow = context.History.SingleOrDefault(x => x.MigrationId == "201607271705375_InitialCreate");
  history.SoftwareVersion = "ABC123";
  context.SaveChanges();
}

问题是 historyRow 始终为空。我发现它为null的原因是因为上下文试图查询历史表,寻找判别器字段设置为" TitanHistoryRow"当该字段实际上保持值" HistoryRow"。我猜这是因为自动迁移默认使用 HistoryContext 而不是我的自定义 TitanHistoryContext ?请帮助:)

{SELECT 
'0X0X' AS [C1], 
[Extent1].[MigrationId] AS [MigrationId], 
[Extent1].[ContextKey] AS [ContextKey], 
[Extent1].[Model] AS [Model], 
[Extent1].[EntityFrameworkVersion] AS [EntityFrameworkVersion], 
[Extent1].[ManifestVersion] AS [ManifestVersion]
FROM [dbo].[__MigrationHistory] AS [Extent1]
WHERE [Extent1].[Discriminator] = N'TitanHistoryRow'}

数据库中的记录如下所示:

 MigrationId                    ContextKey                                  Model            EntityFrameworkVersion  ManifestVersion      Discriminator
201607271705375_InitialCreate   Atl.Titan.Services.DataModel.TitanContext   0x1F8B08000000..  6.1.3-40302             NULL                HistoryRow

=============================================== ============================ 这是我用来自定义__MigrationHistory表的代码:

自定义HistoryRow类

using System.Data.Entity.Migrations.History;

namespace Atl.Titan.Services.DataAccess.Migrations
{
 public class TitanHistoryRow : HistoryRow
 {
    public string SoftwareVersion { get; set; }
 }
}

HistoryContext

using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Migrations.History;

namespace Atl.Titan.Services.DataAccess.Migrations
{
 public class TitanHistoryContext : HistoryContext
 {
    public TitanHistoryContext(DbConnection dbConnection, string defaultSchema)
        : base(dbConnection, defaultSchema)
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Configure table/column names and other properties here if needed
         modelBuilder.Entity<TitanHistoryRow>().Property(p => p.ProductVersion).HasColumnName("EntityFrameworkVersion");
    }

    public new DbSet<TitanHistoryRow> History { get; set; }
 }
}

配置

using System.Data.Entity;

namespace Atl.Titan.Services.DataAccess.Migrations
{
 public class TitanHistoryConfiguration : DbConfiguration
 {
    public TitanHistoryConfiguration()
    {
        this.SetHistoryContext("System.Data.SqlClient",(connection, defaultSchema) => new TitanHistoryContext(connection, defaultSchema));
    }
 }
}

1 个答案:

答案 0 :(得分:0)

如果您尝试让两个类使用同一数据库表(每个层次结构(TPH)继承的AKA表),则Entity Framework将添加一个Discriminator列,并且由于EF的数据库迁移代码明确使用了{{1 }},您的代码将使用DbSet<HistoryRow>,这意味着您无法在包含迁移历史记录数据的同一行中添加任何内容。我要做的是通过在DbSet<TitanHistoryRow>类上使用[Table(MigrationHistory)]属性来使用每类型表(TPT)继承,因此它将有一个单独的表,并且我可以向其中添加具有外部变量的值与TitanHistoryRow表中的MigrationIdContextKey值相匹配的键值,因此__MigrationHistory查询将具有有用的数据,而不是完全独立的数据。 (另请参见此其他人的回答:https://stackoverflow.com/a/24025775/2016290