2012-11-08 26 views
5

Tôi có cài đặt kho chung. Tôi đang sử dụng asp.net mvc C#, mã khuôn khổ thực thể đầu tiên.Kho lưu trữ chung với tính năng xóa mềm

Tôi tạo ra một giao diện mang tên ISoftDelete:

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

tôi thực hiện Delete và GetById trong kho cơ sở của tôi như sau:

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; 
     } 
    } 

Bây giờ, tôi có 2 câu hỏi.

1) Phương pháp này có phải là cách tiếp cận tốt không? Bất kỳ vấn đề nào liên quan đến hiệu suất?

2) chức năng GetAll ban đầu của tôi trong kho cơ bản là như thế này:

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

Làm thế nào tôi có trách nhiệm sửa đổi nó để liệt kê hồ sơ, nơi IsDeleted == false, khi T có nguồn gốc từ ISoftDelete?

Cảm ơn bạn!

Trả lời

4

1) Có vẻ như không ổn khi kiểm tra if (entity is ISoftDelete) mỗi lần bạn cần biết. Nếu bạn chắc chắn rằng bạn sẽ không kiểm tra nó ở bất cứ nơi nào khác nó có thể là ok. Về mặt hiệu suất, sẽ tốt hơn nếu bạn loại bỏ các bản ghi có IsDeleted == true và không bao giờ lấy chúng từ db. Bạn có thể cần phải lấy được một kho lưu trữ cơ sở mới, nó ghi đè các phương thức này và thực hiện các logics mới cho đối tượng 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) có thể là một cái gì như

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

+1 giải pháp tốt đẹp –

+0

public override T GetById (id dài) chức năng này ném một lỗi trên t.Id. – SherleyDev

+0

Nếu bạn đặt một phương thức 'GetById (long id)' trong BaseRepository của bạn, điều này có nghĩa rằng bạn đang giả định bất kỳ cá thể thực thể nào trong dự án của bạn nên có thuộc tính 'long Id'. Để đáp ứng yêu cầu này, bạn có thể định nghĩa một giao diện như 'IEntity {long Id {get; }} 'và áp dụng nó cho tất cả các thực thể. Và lấy được 'ISoftDelete' của bạn từ giao diện này. 'interface ISoftDelete: IEntity {bool IsDeleted {get; bộ; }} '. Và bây giờ SoftDeleteRepository của bạn chắc chắn rằng mỗi cá thể T sẽ có các thuộc tính Id và IsDeleted. –

0

Cách tiếp cận của bạn có vẻ tốt với tôi. Tôi nghĩ rằng đó là pratically không có hiệu suất bị mất exept thử nghiệm trên isDeleted điều kiện, đó là ok. Đối với getAll bạn có thể thử mã này:

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

     return queryable.ToList(); 
    } 
Các vấn đề liên quan