5

汎用リポジトリの実装があります。私はasp.netmvcc#、コードファーストエンティティフレームワークを使用しています。

ISoftDeleteという名前のインターフェイスを作成しました。

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

次のように、ベースリポジトリにDeleteと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();
    }

TがISoftDeleteから派生している場合、IsDeleted == falseであるレコードを一覧表示するには、どのように変更すればよいですか?

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

4

2 に答える 2

4

if (entity is ISoftDelete)1)知る必要があるたびにチェックするのは適切ではないようです。他の場所でチェックしないことが確実な場合は、問題ない可能性があります。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();
于 2012-11-09T07:53:57.460 に答える
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();
    }
于 2012-11-09T07:43:04.667 に答える