You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ASP.NET Core 2中集合内实体软删除失效问题排查

问题分析与解决方案

你的核心问题是:删除集合中的SavePartnerRegistryResource对应实体时,EF执行了硬删除而非软删除,但主实体的软删除功能正常工作。结合你的代码,我梳理了几个最可能的原因及解决办法:

1. 实体排除列表EntitiesToExclude()包含了PartnerRegistry

你的OnBeforeSaving方法里有个关键判断:

if (!EntitiesToExclude().Contains(entry.Entity.ToString()))

如果EntitiesToExclude()返回的列表中包含PartnerRegistry实体的字符串表示(比如完整类型名YourNamespace.PartnerRegistry),那么这个实体的Deleted状态就不会被处理成软删除,EF会直接执行硬删除。

解决办法

  • 检查EntitiesToExclude()方法,确保它没有包含PartnerRegistry的类型字符串。
  • 建议把判断逻辑改成基于类型而非字符串比较,避免ToString()的不确定性:
    var excludedTypes = new List<Type> { typeof(ExcludedEntity1), typeof(ExcludedEntity2) };
    if (!excludedTypes.Contains(entry.Entity.GetType()))
    

2. AfterMap中的删除判断逻辑存在隐患

你当前的删除判断逻辑:

SavePartnerRegistryResource modelPartner = s.Partners.FirstOrDefault(c =>c.PatientFileId == partner.PatientFileId && c.PartnerFileId == partner.PartnerFileId);
if (!s.Partners.Contains(modelPartner)) {
    d.Partners.Remove(partner);
}

modelPartnernull(即传入的DTO中没有匹配的Partner)时,!s.Partners.Contains(modelPartner)会返回true(因为集合中没有null),这时候删除是正确的;但如果DTO的Partners集合中存在null元素,这个逻辑会误删实体。

优化建议
把判断条件改成直接检查modelPartner是否为null,逻辑更清晰准确:

var modelPartner = s.Partners.FirstOrDefault(c => 
    c.PatientFileId == partner.PatientFileId && c.PartnerFileId == partner.PartnerFileId);
if (modelPartner == null) {
    d.Partners.Remove(partner);
}

3. PartnerRegistry的软删除字段映射或配置错误

如果PartnerRegistry实体的IsDeleted属性没有正确映射到数据库字段,或者EF没有追踪到这个属性的变化,那么即使你在OnBeforeSaving中设置了IsDeleted=true,也不会生效,EF依然会执行硬删除。

排查点

  • 确认PartnerRegistry实体中IsDeleted属性的定义(比如是否是bool类型,是否有正确的[Column]注解或Fluent API配置)。
  • 检查数据库中对应的字段是否存在,且类型匹配(比如bit类型)。

4. 验证步骤(快速定位问题)

  1. OnBeforeSavingcase EntityState.Deleted分支中添加调试断点或日志,确认当PartnerRegistry实体被删除时,是否进入了这个分支。
  2. 检查entry.Entity.GetType()是否是PartnerRegistry,且EntitiesToExclude()不包含该类型。
  3. 确认entry.CurrentValues["IsDeleted"]被成功设置为true,且entry.State被改为EntityState.Modified

内容的提问来源于stack exchange,提问作者JSON

火山引擎 最新活动