boring91
boring91

Reputation: 1121

LINQ: Customize the count method

I'm trying to implement a custom LinQ Count() method. Basically what I'm trying to achieve here is before calling the Count method, I want to filter out all elements that have the property IsDeleted set to true. So, I created an extension class and I added these methods:

public static int Count2<T>(this IEnumerable<T> source, Func<T, bool> selector)
    where T : Model
{
    return source.Where(x => !x.IsDeleted).Count(selector);
}

public static int Count2<T>(this IQueryable<T> source, Expression<Func<T, bool>> selector)
    where T : Model
{
    return source.Where(x => !x.IsDeleted).Count(selector);
}

public static int Count2<T>(this IEnumerable<T> source)
    where T : Model
{
    return source.Count(x => !x.IsDeleted);
}

public static int Count2<T>(this IQueryable<T> source)
    where T : Model
{
    return source.Count(x => !x.IsDeleted);
}

This works just find for local collections, but when executing this command for instance:

ListOfModels.Sum(x => x.PropertyThatIsAList.Count2())

and ListOfModels is an instance of IQueryable, i.e. it has to be executed in the database, it gives me this error:

The LINQ expression 'Sum()' could not be translated and will be evaluated locally.

I looked around on the web and I saw some answers saying I have to implement the IQueryableProvider but I think there is no need to go into such complicated path since the Sum() and Count() are translatable, I only need to count conditionally. Is it possible, and if it is, can anyone give me a clue on how to do it?

Upvotes: 1

Views: 294

Answers (1)

shA.t
shA.t

Reputation: 16968

I suggest you instead of customizing all LinQ methods use an extended method like Validate():

public static IEnumerable<T> Validate<T>(this IEnumerable<T> list) where T: IDeleteable
{
    return list.Where(w => !w.IsDeleted);
}

That IDeleteable interface is like this:

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

Then use it before other methods.

Upvotes: 2

Related Questions