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