#entity-framework-core #entity-framework-migrations #entity-framework-core-migrations
#entity-framework-core #entity-framework-миграции #entity-framework-core-миграции
Вопрос:
Я настраиваю Entity Framework Core в новом API для развертывания в существующей базе данных SQL Server, которая используется приложениями Entity Framework 4.6. Существует одна таблица истории миграции, которая является общей для других приложений, и в ней есть 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:
Я просмотрел все решения, но все они показывают, как добавить столбец и установить значение по умолчанию, но не как задать значение динамически. В итоге я углубился в ASP.NET Исходный код Entity Framework Core для решения находится на GitHub, чтобы я мог поделиться им со всеми остальными, поскольку я знаю, что есть другие, которые ищут эту информацию:
Просто переопределите метод GetInsertScript в HistoryRepository и вставьте свои пользовательские значения. Вот полное решение:
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