EF Core 7重复生成Nullable DateTime字段迁移问题求助
问题描述
我拥有包含可空UpdatedDate字段的实体,相关实体初始化代码如下:
var defaultPolicy = new MatchingPolicy() { Id = Guid.Parse("5cf3f8e5-50e1-47c8-aa42-40b1824ea099"), CompanyId = null, Name = "Name", Status = MatchingPolicyStatus.Draft, Type = MatchingPolicyType.Default, Description = "Blabla.", CreatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc).AddTicks(1258), }; var defaultPolicyVersion = new MatchingPolicyVersion() { Id = Guid.Parse("5cf3f8e5-50e1-47c8-aa42-40b1824ea098"), CreatedByUserName = "System", MatchingPolicyId = defaultPolicy.Id, ReviewerUserName = "System", Status = MatchingPolicyApprovalStatus.Approved, Version = 1, CreatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc), UpdatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc), }; var defaultGroups = new[] { new MatchingPolicyGroup { Id = Guid.Parse("1e93b3f9-4ed8-4b90-a859-31b6503ec89f"), MatchingPolicyVersionId = defaultPolicyVersion.Id, Group = MatchingPolicyGroupType.Full, CreatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc).AddTicks(1258), }, new MatchingPolicyGroup { Id = Guid.Parse("b08f004f-a62d-409e-8025-337f0eb73054"), MatchingPolicyVersionId = defaultPolicyVersion.Id, Group = MatchingPolicyGroupType.Possible, CreatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc).AddTicks(1258), }, };
通过以下代码使用HasData将数据添加到数据库:
modelBuilder.Entity<MatchingPolicy>().HasData(defaultPolicy); modelBuilder.Entity<MatchingPolicyVersion>().HasData(defaultPolicyVersion); entity.HasData(defaultGroups); modelBuilder.Entity<Scheme>().Property(u => u.MatchingPolicyId).HasDefaultValue(defaultPolicy.Id);
但EF Core 7始终重复生成相同的迁移,持续更新UpdatedDate字段,即使该迁移已存在。生成的迁移核心代码示例如下:
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.UpdateData( table: "matching_policies", keyColumn: "id", keyValue: new Guid("5cf3f8e5-50e1-47c8-aa42-40b1824ea099"), column: "updated_date", value: null); migrationBuilder.UpdateData( table: "matching_policy_versions", keyColumn: "id", keyValue: new Guid("5cf3f8e5-50e1-47c8-aa42-40b1824ea098"), column: "updated_date", value: new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc)); // 其余matching_policy_groups、matching_rule_templates的UpdateData代码省略 }
已尝试在模型构建器中直接设置字段可空、添加NonGeneratedValue、手动指定DateTime值或设为null,但问题依旧。
解决方案
1. 显式指定种子数据中的UpdatedDate值
对于未显式设置UpdatedDate的实体(如MatchingPolicy、MatchingPolicyGroup),在种子数据初始化时显式将UpdatedDate设为null,消除EF Core对比种子数据与数据库快照时的歧义(未赋值的可空字段会被视为需要更新为默认值)。
修改后的实体初始化示例:
var defaultPolicy = new MatchingPolicy() { // 原有属性... CreatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc).AddTicks(1258), UpdatedDate = null // 显式指定null }; var defaultGroups = new[] { new MatchingPolicyGroup { // 原有属性... CreatedDate = new DateTime(2022, 8, 11, 11, 35, 8, 586, DateTimeKind.Utc).AddTicks(1258), UpdatedDate = null // 显式指定null }, // 第二个Group同理 };
2. 检查并修正数据库快照定义
打开项目中的YourDbContextModelSnapshot.cs文件,确认UpdatedDate字段的定义与实体一致:
- 确认字段标记为可空(
IsNullable = true) - 确认没有多余的生成规则(如
ValueGeneratedOnAddOrUpdate)
若快照定义有误,手动修正后重新生成迁移。
3. 使用HasDefaultValueSql管理默认值
如果UpdatedDate需要默认值,避免用HasDefaultValue硬编码固定值,改用HasDefaultValueSql让数据库处理默认逻辑:
modelBuilder.Entity<MatchingPolicy>() .Property(u => u.UpdatedDate) .HasDefaultValueSql("NULL"); // 或根据业务需求使用CURRENT_TIMESTAMP等
4. 清理并重新生成数据库快照
若上述方法无效,尝试重置迁移环境:
- 删除
Migrations目录下的所有迁移文件 - 删除
YourDbContextModelSnapshot.cs文件 - 运行命令重新生成初始迁移:
dotnet ef migrations add InitialCreate
- 更新数据库:
dotnet ef database update
5. 排除特定字段的种子数据跟踪
如果UpdatedDate不需要在种子数据中维护,可在模型配置中排除该字段的对比逻辑:
modelBuilder.Entity<MatchingPolicy>() .HasData(defaultPolicy) .Ignore(u => u.UpdatedDate); // 从种子数据对比中排除该字段
此方法会让EF Core永远不为该字段生成迁移更新,适合不需要固定种子值的可空字段。
内容的提问来源于stack exchange,提问作者Ashen One
相关产品推荐
相关产品推荐

