2012-11-08 38 views
5

我有一個通用的存儲庫實現。我使用的是asp.net mvc c#,代碼第一個實體框架。具有軟刪除功能的通用存儲庫

我創建了一個名爲ISoftDelete接口:

public interface ISoftDelete 
{ 
    bool IsDeleted { get; set; } 
} 

我實現了我的基礎庫中刪除,並GetById如下:

public virtual void Delete(T entity) 
    { 
     if (entity is ISoftDelete) 
     { 
      ((ISoftDelete)entity).IsDeleted = true; 
     } 
     else 
     { 
      dbset.Remove(entity); 
     } 
    } 

    public virtual T GetById(long id) 
    { 
     T obj = dbset.Find(id); 
     if (obj is ISoftDelete) 
     { 
      if (((ISoftDelete)obj).IsDeleted) 
       return null; 
      else 
       return obj; 
     } 
     else 
     { 
      return obj; 
     } 
    } 

現在,我有2個問題。

1)這種方法是一個好方法嗎?任何性能相關的問題?

2)在基本資料庫我原來GETALL功能是這樣的:

public virtual IEnumerable<T> GetAll() 
    { 
      return dbset.ToList(); 
    } 

我應如何修改它以列表記錄請將isDeleted地方==假的,當T是從ISoftDelete衍生?

謝謝!

回答

4

1)它似乎並不確定每一個你需要知道它的時候檢查if (entity is ISoftDelete)。如果你確定你不打算在任何其他地方檢查它,它可能是好的。在性能方面,如果您選擇的記錄有IsDeleted == true並且從不從數據庫中獲取記錄,那將會更好。您可能需要派生一個覆蓋這些方法併爲ISoftDelete對象實現新邏輯的新基礎存儲庫。

public abstract class BaseRepository<T> 
{ 
    // protected dbset; 

    public virtual void Delete(T entity) 
    { 
     dbset.Remove(entity); 
    } 

    public virtual T GetById(long id) 
    { 
     return dbset.Find(id); 
    } 

    public virtual IEnumerable<T> GetAll() 
    { 
     return dbset.ToList(); 
    } 
} 

public abstract class SoftDeleteRepository<T> : BaseRepository<T> where T : ISoftDelete 
{ 
    public override void Delete(T entity) 
    { 
     entity.IsDeleted = true; 
    } 

    public override T GetById(long id) 
    { 
     return (from t in dbSet 
       where !t.IsDeleted && t.Id == id select t) 
       .FirstOrDefault(); 
    } 

    public override IEnumerable<T> GetAll() 
    { 
     return (from t in dbset where !t.IsDeleted select t).ToList(); 
    } 
} 

public static class RepositoryFactory 
{ 
    public static BaseRepository<T> GetInstance<T>() 
    { 
      // pseudo code 
      if (typeof(T) implements ISoftDelete) 
       return repository of T which extends SoftDeleteRepository 
      return repository of T which extends BaseRepository 
    } 
} 

2)可以是像

return (from t in dbset where 
     (t is ISoftDelete && !(t as ISoftDelete).IsDeleted) || 
     !(t is ISoftDelete)) 
.ToList(); 
+0

1很好的解決方案 –

+0

公共覆蓋ŤGetById(長ID)這個函數拋出上t.Id.錯誤 – SherleyDev

+0

如果你在你的BaseRepository中放置了一個'GetById(long id)'方法,這意味着你假設你的項目中的任何實體實例都應該具有'long ID'屬性。爲了滿足這個要求,你可以定義一個接口,如IEntity {long Id {get; }}'並將其應用於所有實體。並從這個接口派生你的'ISoftDelete'。 'interface ISoftDelete:IEntity {bool IsDeleted {get;組; }}。現在你的SoftDeleteRepository確信每個T實例都有Id和IsDeleted屬性。 –

0

你的方法對我來說似乎很好。我認爲沒有任何性能損失可以免除對isDeleted條件的測試,這是可以的。對於GETALL你可以試試這個代碼:

public virtual IEnumerable<T> GetAll() 
    { 
     var queryable = dbset; 
     if (typeof(ISoftDelete).IsAssignableFrom(typeof(T))) 
     { 
      queryable = queryable.Where(q => q.IsDeleted == false); 
     } 

     return queryable.ToList(); 
    }