Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Repository with Soft Delete Feature

I have a generic repository implementation. I'm using asp.net mvc c#, code first entity framework.

I created an interface named ISoftDelete:

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

I implemented Delete and GetById in my base repository as follows:

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

Now, I have 2 questions.

1) Is this approach is a good approach? Any performance related issues?

2) My original GetAll function in the base repository is like this:

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

How shall I modify it in order to list records where IsDeleted == false, when T is derived from ISoftDelete?

Thank you!

like image 309
SherleyDev Avatar asked Oct 07 '22 01:10

SherleyDev


1 Answers

1) It does not seem ok for checking if (entity is ISoftDelete) every time you need to know it. If you are sure you are not going to check it anywhere else it may be ok. In terms of performance it would be better if you eleminate records that have IsDeleted == true and never fetch them from db. You may need to derive a new base repository which overrides these methods and implements new logics for ISoftDelete object.

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) may be something like

 return (from t in dbset  where 
       (t is ISoftDelete && !(t as ISoftDelete).IsDeleted) || 
       !(t is ISoftDelete))
 .ToList();
like image 146
Mehmet Ataş Avatar answered Oct 10 '22 01:10

Mehmet Ataş