具有软删除功能的通用存储库

She*_*Dev 5 asp.net-mvc repository-pattern ef-code-first

我有一个通用的存储库实现.我正在使用asp.net mvc c#,代码第一个实体框架.

我创建了一个名为ISoftDelete的接口:

public interface ISoftDelete
{
    bool IsDeleted { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我在我的基础存储库中实现了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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在,我有2个问题.

1)这种方法是一种好方法吗?任何性能相关的问题?

2)我在基础存储库中的原始GetAll函数是这样的:

    public virtual IEnumerable<T> GetAll()
    {
            return dbset.ToList();
    }
Run Code Online (Sandbox Code Playgroud)

当从ISoftDelete派生T时,如何修改它以便列出IsDeleted == false的记录?

谢谢!

Meh*_*taş 4

if (entity is ISoftDelete)1)每次需要知道的时候都检查一下似乎不太好。如果您确定不会在其他地方检查它可能没问题。就性能而言,如果删除那些已经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
     }
}
Run Code Online (Sandbox Code Playgroud)

2)可能是这样的

 return (from t in dbset  where 
       (t is ISoftDelete && !(t as ISoftDelete).IsDeleted) || 
       !(t is ISoftDelete))
 .ToList();
Run Code Online (Sandbox Code Playgroud)