1

EntityFramework上软删除的优雅方式是什么?我已经将一个属性(数据库字段)标识为已删除,并始终在 linq 语句上使用此过滤器。

Foo Class  
  int NumberField  
  string Description 
  bool Deleted

contexts.Foos.Where(x=> !x.Deleted);

在复杂的查询上是不可行的。

我只是看了这些解决方案.. Link 1 , Link 2

任何帮助表示赞赏..

4

5 回答 5

2

是的,这可以通过 EF 模式实现。如果您使用 Fascade/repository 模式并每次都通过该 fascade 访问。

例如,所有存储库类上的接口实现可能如下所示:

 class MyRepositoryBase<T>....

    public IQueryable<T> ValidQuerySet  // this is not deleted check  Set

    {  get {  return Context.Set<T>().Where(t => t.deleted != true);
           }
    }

您将完全像访问原始 DbSet 一样访问它。EF 将结合这些条件。

var myQuerySet = MyRespository<T>.ValidQuerySet.Where(t=>t.foo == "bar");
于 2013-02-19T14:33:15.647 回答
1

您可能需要考虑在上下文类本身上创建存储库,而不是直接查询您的上下文(如在此站点上找到)。然后,您可以做的是每当您查询记录时(例如通过使用Filter<T>(Expression<Func<T, bool>> predicate)存储库的方法,您始终可以执行以下操作:

return Context.Set<Foo>().Where<Foo>(x => !x.Deleted).Where<Foo>(predicate).AsQueryable<Foo>();

更好的是,如果您要在多个对象类型中实现该软删除,然后将其拉入一个抽象类(SoftDeleteable例如调用它),那么您的 Filter 方法签名可能是:

public virtual IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate) where T : SoftDeletable
于 2013-02-19T14:27:38.530 回答
0

您可能不会喜欢我的回答,但我能想到的“不那么痛苦”的方式需要大量存储过程:每个实体 1 个,而您所做的只是如果存在 UPDATE foo Deleted = True。我的通常看起来像这样

PROCEDURE [dbo].[SP_Address_UnSet]
    @ID bigint
AS
BEGIN
    DECLARE @IsInactive bit

    SELECT @IsInactive = IsInactive
    FROM [Address]
    WHERE AddressID = @ID

    IF (0 = @@ROWCOUNT)
        RETURN -1

    -- implicit else

    IF (1 = @IsInactive)
        RETURN 0

    -- implicit else

    UPDATE [Address]
    SET IsInactive = 1
    WHERE AddressID = @ID

    RETURN @@ROWCOUNT -- should be 1
END

然后在每个实体上映射到该 SP。

您可以有 1 个单一的 SP,并将表名作为参数传递,但由于您不能通过动态查询直接在 T-SQL 中使用它,因此您必须构建子执行(并担心 SQL 注入!!)

Exec('SELECT * FROM ' + @tableName)
于 2013-08-09T14:32:15.000 回答
0

全局查询过滤器 (EF Core)实体框架拦截器 (EF 6+)是在 EntityFramework 上添加的新功能,用于解决此类问题。

于 2019-01-09T10:39:49.947 回答
-1

我发现以这种方式进行“软删除”非常痛苦:

  1. 当你进行数据访问时,你必须在任何地方记住这个标志。是的,您可以将它包装在一些存储库模式中,但您仍然可以在任何地方使用它。
  2. 您的表格很快就充满了“已删除”的条目,使报告、分析效率低下。

我建议您将硬“已删除”条目放入不同的表或数据库中,从长远来看,它将为您节省时间。

于 2013-02-19T16:07:16.647 回答