简体   繁体   English

EF Core > 删除实体(软删除)> 实体 State 保持不变

[英]EF Core > Delete entity (Soft Delete) > Entity State remains Unchanged

In my generic base repository I have the following simple method for removing an entity from database:在我的通用基础存储库中,我有以下从数据库中删除实体的简单方法:

    public async Task<bool> DeleteAsync(TKey id)
    {
        var item = await Context.Set<TDb>().FindAsync(id).ConfigureAwait(false);
        if (item == null)
            return null;

        var result = Context.Set<TDb>().Remove(item);
        await Context.SaveChangesAsync().ConfigureAwait(false);

        return result.State == EntityState.Modified || result.State == EntityState.Deleted;
    }

Then in my DB Context I do set shadow properties in my save changes async in a following way (just like Microsoft suggests) (code simplified for better clarity):然后在我的数据库上下文中,我确实以以下方式在我的保存更改中设置了阴影属性(就像微软建议的那样)(为了更清晰而简化了代码):

public class EfCoreDbContext : DbContext, IUnitOfWork
{
    public EfCoreDbContext(
        DbContextOptions options
        IConfiguration configuration) : base(options)
    {
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        ChangeTracker.SetShadowISoftDeletableProperties();
        ChangeTracker.SetShadowIUserOwnableProperties(UserResolver);
        ChangeTracker.SetShadowIAuditableProperties(UserResolver);
        return await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
    }
}

As visible from SaveChangesAsync method, I already use shadow properties for other tracking items, such as audits, or user ownership which works without a problem.SaveChangesAsync方法可以看出,我已经将影子属性用于其他跟踪项目,例如审计或用户所有权,这些都可以正常工作。

Finally, here is the Change Tracker code responsible for setting up soft delete最后,这里是负责设置软删除的 Change Tracker 代码

    public static void SetShadowISoftDeletableProperties(this ChangeTracker changeTracker)
    {
        changeTracker.DetectChanges();
        foreach (var entry in changeTracker.Entries())
        {
            if (typeof(ISoftDeletable).IsAssignableFrom(entry.Entity.GetType()))
            {
                if (entry.State == EntityState.Deleted)
                {
                    entry.State = EntityState.Modified;
                    entry.Property("IsDeleted").CurrentValue = true;
                }
                else if (entry.State == EntityState.Added)
                {
                    entry.Property("IsDeleted").CurrentValue = false;
                }
                else
                {
                    entry.Property("IsDeleted").CurrentValue = entry.Property("IsDeleted").OriginalValue;
                }
            }
        }
    }

Everything works fine, IsDeleted property is being set successfully in the database;一切正常, IsDeleted属性已在数据库中成功设置; however when I inspect my result.State , it tells me that entity state is Unchanged (which causes that my DeleteAsync returns false ), which I don't quite understand.但是,当我检查我的result.State时,它告诉我实体 state 是Unchanged (这导致我的 DeleteAsync 返回false ),我不太明白。 Even in code it is visible, that I change state from Deleted to Modified .即使在代码中也可以看到,我将 state 从Deleted更改为Modified

I can surely ignore this and instead, return plain true after saving changes (in case of error, it would fail before);我当然可以忽略这一点,而是在保存更改后返回纯真(如果出现错误,它会在之前失败); yet I am just trying to understand why I am getting this unexpected state result.但我只是想了解为什么我会得到这个意想不到的 state 结果。 Any help in respect to this matter would be highly appreciated.对此问题的任何帮助将不胜感激。

Added , Modified and Deleted are pending states, indicating what EF Core will do with that entity when SaveChanges{Async} is called. AddedModifiedDeleted挂起状态,指示调用SaveChanges{Async}时 EF Core 将对该实体执行的操作。 ChangeTracker.HasChanges() returns true when there is any entity entry with such state.当存在任何具有此类 state 的实体条目时, ChangeTracker.HasChanges()返回 true。

By default ( acceptAllChangesOnSuccess=true parameter of SaveChanges{Async} ), after successful SaveChanges these states are updated to reflect the permanent (database) state of these entities.默认情况下( SaveChanges{Async}acceptAllChangesOnSuccess=true参数),在SaveChanges成功后,这些状态会更新以反映这些实体的永久(数据库)state。 Added and Modified become Unchanged , Deleted become Detached (and entries are removed from the change tracker) and ChangeTracker.HasChanges() returns false. AddedModified变为UnchangedDeleted变为Detached (并且条目从更改跟踪器中删除)并且ChangeTracker.HasChanges()返回 false。

You can change that by passing acceptAllChangesOnSuccess=false to SaveChanges{Async} , in which case you'll see the pending states, but then you should not forget to call ChangeTracker.AcceptAllChanges() , otherwise the next SaveChanges{Async} will try to reapply them in the database (and most likely will fail).您可以通过将acceptAllChangesOnSuccess=false传递给SaveChanges{Async}来更改它,在这种情况下您会看到挂起的状态,但是您不应该忘记调用ChangeTracker.AcceptAllChanges() ,否则下一个SaveChanges{Async}将尝试在数据库中重新应用它们(很可能会失败)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM