2017-01-24 49 views
0

我想更改EF在删除记录时的工作方式。 而不是删除数据库中的行,它应该填充一列(GCC列左右)。实体框架不删除记录,但填充列

当检索数据时,它应该总是过滤GCC column IS NULL +你应用的过滤器。

任何人都知道这是可以实现的以及如何实现?

+1

所以它实际上是一个更新不能删除?并选择一个预定义的过滤器。告诉我你到目前为止尝试过什么 –

+0

我还没有尝试过任何东西,我想知道是否有开箱即用的解决方案。我正在考虑添加EFHooks并修复它。 –

+0

但为什么现在要使用EF提供的方法。为什么要系统,如果你已经解决,在这种情况下是简单的ASW ELL –

回答

0

我除了上面的回答,考虑很多甚至所有的实体都有这个GCColumn的情况。

,您可以用这些伪删除的实体基础机构开始:

public abstract class PseudoDeletable 
{ 
    public DateTime GCColumn { get; set;} 
} 

,并具有定义为实体:

public class Order : PseudoDeletable 
{ 
    public int Id { get; set; } 
    public int ProductId { get; set; } 
    public DateTime OrderDate { get; set; } 
    // etc. 
} 

然后,你可以创建一个通用的基础库

public class RepositoryBase<TEntity> where TEntity : PseudoDeletable 
{ 
    protected IDbSet<TEntity> DbSet { get; } 

    public RepositoryBase() 
    { 
     DbSet = context.Set<TEntity>(); 
    } 

    private Expression<Func<TEntity, bool>> RemoveDeleted 
    { 
     get { return e => e.GCColumn == null; } 
    } 

    public virtual IEnumerable<TEntity> GetAll(Expression<Func<TEntity, bool>> expression) 
    { 
     expression = expression.And(RemoveDeleted); 
     return DbSet.Where(expression).ToList(); 
    } 
} 

,并已衍生库,如:

public class OrderRepository : RepositoryBase<Order> 
{ 
} 

GetAll方法就可以这样调用:

new orderRepository().GetAll(x => x.ProductId == 1); 

,它只会返回一个没有被删除的订单。

请注意,您将在entity includes的相关记录中遇到问题:如何仅包含未删除的相关实体,但这是您希望将“已删除”记录保留在数据库中的结果。

+0

谢谢,生病尝试并执行此操作! –

0

在一个项目中,我们使用存储库模式进行数据库访问,每个实体都有自己的存储库。

它是一个多租户数据库,我们使用您正在查找的过滤器类型来过滤当前用户可访问的实体,而不是过滤删除标志,但可以类似地使用该方法。

每个库,需要滤波,得到一个过滤方法:

private Expression<Func<Order, bool>> RemoveDeleted 
{ 
    get 
    { 
     return order => order.GCColumn == null; 
    } 
} 

然后,添加一个表达式每个库方法,如:

public override IEnumerable<Order> GetAll(Expression<Func<Order, bool>> expression) 
{ 
    expression = expression.And(RemoveDeleted); 
    return DbSet.Where(expression).ToList(); 
} 

扩展方法Add来自一个一套ExpressionExtensions

现在,您可以使用像这样的表达式:

orderRepository.GetAll(x => x.ProductId == productId); 

orderRepository.GetAll(x => x.OrderDate >= DateTime.Now.AddMonths(-1)); 

所以,现在你的业务逻辑可以使用相同的GETALL()方法,用不同的过滤方法很多,但不必在意“删除”实体。但是您仍然需要为每个存储库方法创建正确的过滤器。

如果删除标志并非在所有的实体,但删除状态的另一个实体注册,您可以执行以下操作:

private Expression<Func<Order, bool>> RemoveDeleted 
{ 
    get 
    { 
     return orderLine => orderLine.Order.GCColumn == null; 
    } 
} 

在这个例子中订单的整体,而不是单独的线路被删除它。

+0

作为安全防范,你可以申请中描述的方法[教程:使用多租户数据库使用实体框架和行级安全的Web应用程序(https://docs.microsoft.com/en-us/azure/如果您使用的是SQL Server 2016或更高版本,则可以使用以下代码:app-service-web/web-sites-dotnet-entity-framework-row-level-security)。 –