2012-11-08 3 views
5

私は一般的なリポジトリ実装を持っています。私はasp.net mvc C#、コードの最初のエンティティフレームワークを使用しています。次のように私は私のベースのリポジトリ内の削除とGetByIdを実装ソフト削除機能を備えた汎用リポジトリ

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

::私はISoftDeleteという名前のインターフェイスを作成し

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 == falseを、TはISoftDeleteから派生したとき?

ありがとうございました!

答えて

4

1):のgetAllのためには、このコードを試すことができます。あなたがどこにいてもそれをチェックしないと確信しているなら、それは大丈夫かもしれません。パフォーマンスに関しては、IsDeleted == trueのレコードを除外し、dbからフェッチしないようにする方がよいでしょう。これらのメソッドをオーバーライドし、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

公共オーバーライドT GetById(長いID)この関数はt.Id.にエラーをスローするようなものであってもよいです – SherleyDev

+0

BaseRepositoryに 'GetById(long id)'メソッドを置くと、これは、プロジェクトのエンティティインスタンスに '長いId'プロパティがあると仮定していることを意味します。この要件を満たすためには、 'IEntity {long Id {get; }} 'を作成し、すべてのエンティティに適用します。このインターフェースから 'ISoftDelete'を引き出します。 'インターフェイスISoftDelete:IEntity {bool IsDeleted {get;セット; }} '。そして、あなたのSoftDeleteRepositoryは、各TインスタンスがIdとIsDeletedプロパティを持つことを確信しています。 –

0

あなたのアプローチは私にとっては良いようです。私は正常にisDeleted条件でテストを実行してもパフォーマンスが失われているとは思えません。それはあなたがそれを知っている必要がありますたびにif (entity is ISoftDelete)チェックするためのOKは思えない

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

     return queryable.ToList(); 
    } 
関連する問題