ebram khalil
ebram khalil

Reputation: 8321

EF Code First check for property in generic repository

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?

Upvotes: 1

Views: 414

Answers (2)

ebram khalil
ebram khalil

Reputation: 8321

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

Upvotes: 0

SoftwareFactor
SoftwareFactor

Reputation: 8588

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.

Upvotes: 1

Related Questions