EFCore 3 在每次迁移中为种子数据生成更新
EFCore 3 generate update for seed data in every migrations
将我的项目从 dotnet core 2.2 更新到 3.1 之后。现在,在 运行 migrations add
命令之后,新迁移包含所有种子数据的更新。
public class MyEntity
{
public Guid Id { get; private set; }
public string Code { get; private set; }
public string Title { get; private set; }
public bool IsActive { get; private set; }
private MyEntity() { }
[JsonConstructor]
public MyEntity(Guid id, string code, string title)
{
Id = id;
Title = title;
Code = code;
IsActive = true;
}
}
public class MyEntityEntityTypeConfiguration
: IEntityTypeConfiguration<MyEntity>
{
public void Configure(EntityTypeBuilder<MyEntity> configuration)
{
configuration.HasKey(b => b.Id);
configuration.Property(b => b.Title).HasMaxLength(150).IsRequired();
configuration.Property(b => b.Code).HasMaxLength(20).IsRequired();
configuration.Property(c => c.IsActive).HasDefaultValue(true);
configuration.HasData(
new MyEntity(new Guid("3274D8FD-DFAE-4396-8DD0-89A6F5107DB1"), "1", "titl1")
);
}
}
这是迁移中不需要的部分,此代码存在于所有功能迁移中。
migrationBuilder.UpdateData(
schema: "dbo",
table: "MyEntity",
keyColumn: "Id",
keyValue: new Guid("08f2aa3d-ad4c-4a82-987c-ff43527466e0"),
column: "IsActive",
value: true);
我在更新到 dotnet core 3.1 之前没有这个更新。
有什么变化?
正在跟踪此问题 here。
我在自己的项目中使用的解决方法是忽略所有 种子数据更新;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "Workaround")]
public class ModelDiffer : MigrationsModelDiffer
{
public ModelDiffer(
IRelationalTypeMappingSource typeMappingSource,
IMigrationsAnnotationProvider migrationsAnnotations,
IChangeDetector changeDetector,
IUpdateAdapterFactory updateAdapterFactory,
CommandBatchPreparerDependencies commandBatchPreparerDependencies) :
base(typeMappingSource, migrationsAnnotations, changeDetector, updateAdapterFactory, commandBatchPreparerDependencies)
{
}
//FIXME Remove when https://github.com/aspnet/EntityFrameworkCore/issues/18943 is deployed
public override IReadOnlyList<MigrationOperation> GetDifferences(IModel source, IModel target)
{
return base.GetDifferences(source, target)
.Where(o => !(o is UpdateDataOperation))
.ToList();
}
}
services.AddDbContextPool<Context>(o =>
{
o.ReplaceService<IMigrationsModelDiffer, ModelDiffer>();
o.UseSqlServer(connectionString, ...
}
在我的例子中,我不得不依赖 project issue 中建议的解决方法 - 确保每个默认值定义后也跟着 ValueGeneratedNever()
。示例:
entity.Property(e => e.DateCreation)
.HasColumnType("datetime")
.HasDefaultValueSql("(getutcdate())")
.ValueGeneratedNever();
将我的项目从 dotnet core 2.2 更新到 3.1 之后。现在,在 运行 migrations add
命令之后,新迁移包含所有种子数据的更新。
public class MyEntity
{
public Guid Id { get; private set; }
public string Code { get; private set; }
public string Title { get; private set; }
public bool IsActive { get; private set; }
private MyEntity() { }
[JsonConstructor]
public MyEntity(Guid id, string code, string title)
{
Id = id;
Title = title;
Code = code;
IsActive = true;
}
}
public class MyEntityEntityTypeConfiguration
: IEntityTypeConfiguration<MyEntity>
{
public void Configure(EntityTypeBuilder<MyEntity> configuration)
{
configuration.HasKey(b => b.Id);
configuration.Property(b => b.Title).HasMaxLength(150).IsRequired();
configuration.Property(b => b.Code).HasMaxLength(20).IsRequired();
configuration.Property(c => c.IsActive).HasDefaultValue(true);
configuration.HasData(
new MyEntity(new Guid("3274D8FD-DFAE-4396-8DD0-89A6F5107DB1"), "1", "titl1")
);
}
}
这是迁移中不需要的部分,此代码存在于所有功能迁移中。
migrationBuilder.UpdateData(
schema: "dbo",
table: "MyEntity",
keyColumn: "Id",
keyValue: new Guid("08f2aa3d-ad4c-4a82-987c-ff43527466e0"),
column: "IsActive",
value: true);
我在更新到 dotnet core 3.1 之前没有这个更新。 有什么变化?
正在跟踪此问题 here。
我在自己的项目中使用的解决方法是忽略所有 种子数据更新;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "Workaround")]
public class ModelDiffer : MigrationsModelDiffer
{
public ModelDiffer(
IRelationalTypeMappingSource typeMappingSource,
IMigrationsAnnotationProvider migrationsAnnotations,
IChangeDetector changeDetector,
IUpdateAdapterFactory updateAdapterFactory,
CommandBatchPreparerDependencies commandBatchPreparerDependencies) :
base(typeMappingSource, migrationsAnnotations, changeDetector, updateAdapterFactory, commandBatchPreparerDependencies)
{
}
//FIXME Remove when https://github.com/aspnet/EntityFrameworkCore/issues/18943 is deployed
public override IReadOnlyList<MigrationOperation> GetDifferences(IModel source, IModel target)
{
return base.GetDifferences(source, target)
.Where(o => !(o is UpdateDataOperation))
.ToList();
}
}
services.AddDbContextPool<Context>(o =>
{
o.ReplaceService<IMigrationsModelDiffer, ModelDiffer>();
o.UseSqlServer(connectionString, ...
}
在我的例子中,我不得不依赖 project issue 中建议的解决方法 - 确保每个默认值定义后也跟着 ValueGeneratedNever()
。示例:
entity.Property(e => e.DateCreation)
.HasColumnType("datetime")
.HasDefaultValueSql("(getutcdate())")
.ValueGeneratedNever();