从DbSet<TEntity>加载时,基于属性IsDeleted值排除实体。

3
我正在使用Entity Framework,我在上下文中做了一些事情,例如:
public override int SaveChanges()
{
    foreach (var entry in ChangeTracker.Entries())
    {
        if (entry.Entity is Base entity)
        {
            if (entry.State == EntityState.Added)
            {
                entity.Created = DateTime.UtcNow;
                entity.Modified = DateTime.UtcNow;
            }
            else if (entry.State == EntityState.Modified)
            {
                entity.Modified = DateTime.UtcNow;
            }
        }
    }
    return base.SaveChanges();
}

其中Base是:

    public int Id { get; set; }
    public DateTime? Created { get; set; }
    public DateTime? Modified { get; set; }
    public bool IsDeleted { get; set; }

现在我要做的是,当我使用我的上下文加载属性时,例如:
_context.MyEntities.AsEnumerable(something);

我希望选择所有 IsDeleted 属性设置为 false 的实体。在 DbContext 中是否可以像覆盖 SaveChanges() 一样实现这一点?
我能看到有一个要重写的方法,但不确定如何进行操作:
public override DbSet<TEntity> Set<TEntity>()
{
    return base.Set<TEntity>();
}

你在寻找 _context.MyEntities.Where(x => !x.IsDeleted).ToList() 吗?调用 .AsEnumerable() 会将整个表格下载到内存中,请注意。 - Camilo Terevinto
@CamiloTerevinto 不,我不想这样做,因为每次加载实体时都需要检查删除标志。我想知道是否有一种方法可以在更低的级别上使用上下文对象排除已删除的实体。 - px06
什么 EF 版本?您可以在 6+ 和 Core 2+ 中透明地处理软删除。 - Aluan Haddad
@AluanHaddad 确实使用 EF6 和 MVC5。 - px06
如果您想要软删除,请观看Rowan Miller的此演示文稿。请在大约11分钟处查看软删除内容。 - Aluan Haddad
1个回答

2
如果我理解正确,您需要在 DbContext 中添加类似以下内容的代码。
public DbSet<MyEntity> ExistingMyEntities {
    get { return MyEntities.Where(x => !x.IsDeleted); }
}

所以,您可以使用上下文对象来检索未删除的实体。

更新

如果使用软删除(如何使用Entity Framework自动过滤软删除的实体?),也可以通过模型生成器按IsDeleted进行过滤。

public class MyContext : DbContext
{
    public virtual IDbSet<MyEntity> MyEntities { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyEntities>()
            .Map(m => m.Requires("IsDeleted")).HasValue(false).Ignore(m => m.IsDeleted);
    }
}

我之前误解了 Ignore(忽略)的功能,但是像 Jan Muncinsky 提到的那样,可以使用 HasValue 方法进行筛选。

1
Ignore(m => m.IsDeleted) 不会过滤任何东西,它只会在映射过程中忽略该属性。 - Jan Muncinsky
https://putshello.wordpress.com/2014/08/20/entity-framework-soft-deletes-are-easy/ - Daniil Grankin
你可以通过以下方式进行过滤:modelBuilder.Entity<Base>().Map(m => m.Requires("IsDeleted").HasValue(false))。但是这将需要从模型中删除 IsDeleted 并仅在数据库中保留它,因此在这种情况下并不实用。 - Jan Muncinsky
@JanMuncinsky 不需要将其从模型中移除。但是没有理由将其放在模型中,因为检索到的所有实体的属性值都将为false。 - Daniil Grankin
@JanMuncinsky 我猜这里使用了软删除,而不是通过属性 https://dev59.com/V2cs5IYBdhLWcg3woFbt - Daniil Grankin
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接