1
\$\begingroup\$

I want to have a cross-cutting delete flag in my repository. I have the following repository pattern at the moment:

public interface IRepo<TModel> where TModel : EntityBase<int>
    {
        TModel Add(TModel item);
        void Add(IEnumerable<TModel> entities);
        TModel Remove(TModel item);
        TModel Find(int itemId);
        TModel Get(int itemId);
        IQueryable<TModel> Query { get; }
    }

I am exposing IQueryable which makes it hard to control whether deleted entities are retrieved or not in my service layer. Would adding a method to my repository which replaces Query and exposes a pre-filtered IEnumerable be bad form?

public IEnumerable<TEntity> GetAll
{
    get { return this.dbset.AsEnumerable().Where(x => x.IsDeleted == false); }
}

I am assuming since IQueryable is lazily loaded I won't pulling more entities into memory than required? Is this naive?

\$\endgroup\$
3
  • 2
    \$\begingroup\$ You don't need AsEnumerable(). Return IQueryable<TEntity> and just do return dbSet.Where(x => !x.IsDeleted);. You've stumbled across one of the many reasons I dislike having a "standard" repository interface though. \$\endgroup\$
    – RobH
    Jul 29, 2015 at 14:45
  • \$\begingroup\$ @RobH - thanks for the comment. Do you want to leave this as an answer? I feel it satisfies the question. \$\endgroup\$
    – Alex
    Jul 31, 2015 at 9:29
  • \$\begingroup\$ slightly expanded on my comment in an answer for you \$\endgroup\$
    – RobH
    Jul 31, 2015 at 9:47

1 Answer 1

1
\$\begingroup\$

You don't need to call AsEnumerable on the DbSet in fact, doing so isn't great at all... As far as I am aware, this will make your Where clause execute in C# rather than being translated to SQL meaning a massive perf hit (I would be happy to be corrected here).

You should return IQueryable<TEntity> directly:

return dbSet.Where(x => !x.IsDeleted);

Notice that I've removed the redundant this. and also changed the comparison to use ! (not operator) instead of comparing to false.

One additional warning I would give you is: are you sure you need a generic base class repository? I find that when I have used this pattern a lot of my repositories get methods they never use.

It can also be argued that it's a leaky abstraction, see e.g here and here

I prefer slim interfaces of only a few methods rather than using header interfaces.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.