2017-01-24 53 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)。 –