1

In my project, I'm using EF Code First approach following Code Camper structure. So i have generic repository IRepository;

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    T GetById(int id);
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(int id);
}

and then it's implementation EFRepository<T>

public class EFRepository<T> : IRepository<T> where T : class
{
    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null) 
            throw new ArgumentNullException("dbContext");
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();
    }

    protected DbContext DbContext { get; set; }

    protected DbSet<T> DbSet { get; set; }

    public virtual IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public virtual T GetById(int id)
    {
        //return DbSet.FirstOrDefault(PredicateBuilder.GetByIdPredicate<T>(id));
        return DbSet.Find(id);
    }

    public virtual void Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
    }

    public virtual void Update(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State == EntityState.Detached)
        {
            DbSet.Attach(entity);
        }  
        dbEntityEntry.State = EntityState.Modified;
    }

    public virtual void Delete(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Deleted)
        {
            dbEntityEntry.State = EntityState.Deleted;
        }
        else
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }
    }

    public virtual void Delete(int id)
    {
        var entity = GetById(id);
        if (entity == null) return; // not found; assume already deleted.
        Delete(entity);
    }
}

Based on customer needs, i should not delete any DB records, so for most(not all of them) tables I have isDeleted property to mark record as deleted. And these records which marked as isDeleted should not appear to users

My question is: How in my generic repository implementation check for that isDeleted property while I'm expecting generic object T. For example GetAll function should be:

public virtual IQueryable<T> GetAll()
{
    return DbSet.where(x=>x.isDelete == false);
}

Any ideas, how i can do that?

ebram khalil
  • 8,252
  • 7
  • 42
  • 60

2 Answers2

1

Create an interface with IsDeleted property and inherit all your models from it. Then you could modify your repository like this:

public class EFRepository<T> : IRepository<T> where T : TypeOfYourNewInterface

Now you can access IsDeleted in generic methods.

SoftwareFactor
  • 8,430
  • 3
  • 30
  • 34
  • and what for the models that does not have `isDeleted` ? – ebram khalil Jun 10 '14 at 09:44
  • You could use two implementations of repository class – SoftwareFactor Jun 10 '14 at 09:49
  • @ebramtharwat why do you have Delete Methods in the generic repository in the first place if you don't want your models to be deleted? – Larry Jun 10 '14 at 09:50
  • @Larry Good point. i was just following Code Camper structure. and in some rare cases or for some models, i 'll need to delete the DB records – ebram khalil Jun 10 '14 at 09:54
  • @ebramtharwat can you have a repositoryFactory class, in the factory, you will check if your model implements 'IsDeletable' interface using reflection and create repository for you. In such case you will probably need two genericrepository class definitions. – Larry Jun 10 '14 at 10:11
0

I could not find a suitable solution to my problem. After more searching i ended with 3 solutions:

  1. Create extension methods.
  2. Create a custom IDbSet which can accept a filter expression.
  3. Add a discriminator to every model.

I choosed solution(3) although, I don't like it much

Community
  • 1
  • 1
ebram khalil
  • 8,252
  • 7
  • 42
  • 60