5

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

我创建了一个名为 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 回答