Entity Framework Owned Type软删除异常问题求助
EF Core 软删除结合Owned Type时避免字段被设为NULL的解决办法
问题核心:实现软删除时将实体状态从Deleted改为Modified,但添加Owned Type后,EF Core会尝试将Owned Type的所有字段置为NULL,导致非空字符串字段报错。
解决方案一:配置Owned Type的删除行为为NoAction
在实体配置类中,显式设置Owned Type与主实体的删除行为为NoAction,阻止EF自动对Owned Type执行级联置空操作。
修改后的MainEntityConfiguration.cs:
public class MainEntityConfiguration : IEntityTypeConfiguration<MainEntity> { public void Configure(EntityTypeBuilder<MainEntity> builder) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } builder.HasKey(x => x.Id); builder.Property(x => x.Id).ValueGeneratedOnAdd(); // 配置Owned Type并指定删除行为 builder.OwnsOne(o => o.MultilangTitle, ownedBuilder => { // 设置删除行为为NoAction,避免EF尝试清空Owned Type字段 ownedBuilder.WithOwner().OnDelete(DeleteBehavior.NoAction); // 显式标记字符串字段为必填,确保EF映射数据库非空约束 ownedBuilder.Property(s => s.En).IsRequired(); ownedBuilder.Property(s => s.Fr).IsRequired(); }); } }
解决方案二:同步Owned Type的实体状态
在SaveChanges方法中,修改主实体状态为Modified后,需要将Owned Type的实体状态也设为Modified,避免其被标记为Deleted触发清空操作。
修改后的ApplicationDbContext.cs:
public override int SaveChanges() { var softDeleteEntries = ChangeTracker.Entries<ISoftDeleteEntityBase>(); foreach (var entry in softDeleteEntries) { if (entry.State == EntityState.Deleted) { entry.State = EntityState.Modified; entry.Entity.DeletedBy = creator; entry.Entity.Deleted = DateTime.Now; // 遍历并同步所有Owned Type的状态 foreach (var navEntry in entry.Navigations) { if (navEntry.Metadata.IsOwned()) { navEntry.Load(); // 确保加载Owned Type实体 var ownedEntry = ChangeTracker.Entries().FirstOrDefault(e => e.Entity == navEntry.CurrentValue); if (ownedEntry != null) { ownedEntry.State = EntityState.Modified; } } } } } return base.SaveChanges(); }
原理说明
- 默认情况下,EF Core对Owned Type的删除行为是
Cascade,当主实体被标记为Deleted时,会自动将Owned Type的所有字段置为NULL。通过OnDelete(DeleteBehavior.NoAction)可以禁用这一行为。 - 手动同步Owned Type的状态,确保其与主实体保持一致的
Modified状态,从根源上避免EF触发清空字段的逻辑。
内容的提问来源于stack exchange,提问作者nino
相关产品推荐
相关产品推荐

