0

我有EF代碼優先解決方案,它支持軟刪除,因此我們將實體標記爲IsDeleted,而不是從數據庫中刪除它們。 我想整理相關對象的集合(延遲加載),因此標記爲已刪除的實體不會返回給API用戶。EF 4.1代碼首先過濾延遲加載的集合

下面是簡單的approache我用:

public class FilteredCollection<T> : ICollection<T> where T : DeletableEntity 
{ 
    private List<T> _listWithDeleted = new List<T>(); 

    protected IEnumerable<T> FilteredItems 
    { 
     get { return _listWithDeleted.Where(e => e.IsDeleted == false); } 
    } 

    protected bool _IsReadOnly; 

    public virtual T this[int index] 
    { 
     get 
     {     
      return FilteredItems.ToList()[index]; 
     } 
     set 
     { 
      FilteredItems.ToList()[index] = value; 
     } 
    } 

    public virtual int Count 
    { 
     get 
     { 
      return FilteredItems.Count(); 
     } 
    } 

    public virtual bool IsReadOnly 
    { 
     get 
     { 
      return _IsReadOnly; 
     } 
    } 

    public virtual void Add(T entityObject) 
    { 
     _listWithDeleted.Add(entityObject); 
    } 

    public virtual bool Remove(T entityObject) 
    { 
     if (FilteredItems.Contains(entityObject)) 
     { 
      entityObject.IsDeleted = true; 
      return true; 
     } 
     else 
     { 
      return false;  
     } 
    } 

    public bool Contains(T entityObject) 
    { 
     return FilteredItems.Contains(entityObject); 
    } 

    public virtual void CopyTo(T[] entityObjectArray, int index) 
    { 
     var list = FilteredItems.ToList(); 
     list.CopyTo(entityObjectArray, index); 
    } 

    public virtual void Clear() 
    { 
     foreach (var item in _listWithDeleted) 
     { 
      item.IsDeleted = true; 
     } 
    } 

    public virtual IEnumerator<T> GetEnumerator() 
    { 
     return FilteredItems.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return FilteredItems.GetEnumerator(); 
    } 
} 

我已經實現的ICollection所以內部過濾器對象。我使用這個類而不是ICollection,所以過濾的實體返回給我。 我已經做了一些測試,看起來效果很好,但我對這個解決方案感到不舒服。

請給我提供這種方法的缺點或請建議,以防萬一你知道一些更好的。

由於事前,

-Petro

回答

1

這是錯誤的解決方案,因爲它使過濾在應用程序中。如果您的數據庫將會增長並且會有越來越多的軟刪除項目,您將始終需要在應用過濾器之前加載所有這些項目。這可能會很快成爲非常大的性能問題。

您應該在數據庫中進行篩選,但這不符合惰性和熱切加載的要求。解決方案可以是條件映射(只有未刪除的項目將被映射),但它不會允許映射IsDeleted屬性 - 您必須用存儲過程軟刪除您的實體,並且不能先用代碼映射。

結合使用EF代碼優先+軟刪除,您應該完全避免懶惰和急切加載,或者使用單獨的查詢來獲取過濾的數據或使用顯式加載。