0

Consider the function:

public async Task<IEnumerable<Purchases>> GetPurchases(User user, Expression<Func<Purchases, bool>> whereClause)
    {           
            using (var context = new UserDbContext())
            {
                context.Users.Attach(user);
                context.Entry(user).Collection(p => p.Purchases)
                .Query()
                .Where(whereClause)
                .Load();

                if (Equals(user.Purchases, null))
                    return new List<Purchases>();
            }

        return user.Purchases;
}

In this function the parameter whereClause can at times be null, I'm wanting to check if its null and then assign an empty Expression if so. This is as close as I've come:

if (Equals(whereClause, null))
       whereClause = () => { };

This was based on the question here, but for the line that makes whereClause empty I'm getting the error.

Error 7 Not all code paths return a value in lambda expression of type 'System.Func'<'Purchases,bool>'

Anyone know how this could be corrected?

Community
  • 1
  • 1
Faraji Anderson
  • 653
  • 6
  • 18

3 Answers3

4

"Not all code paths return a value" means your lambda isn't returning anything. I mean, it's got only one code path, and it's not a long one.

Where requires a lambda which takes one parameter, and returns bool. Where won't let you give it an empty lambda expression.

You need to give it something it can use to filter items with.

That's actually easy:

if (Equals(whereClause, null))
    whereClause = o => true;

That's a where clause that always returns true, regardless of what you give it. That's probably what you want: If there's no filter, include everything. For each item in the enumeration, one at a time, Where gives the lambda the item as o. If the lambda returns true, it includes that value of o in the results.

If you want a null filter to return no items, just return false instead:

if (Equals(whereClause, null))
    //  Whatever it is, I'm against it.
    whereClause = o => false;
1

whereClause must return a boolean value to use it in LinQs Where method.

Assuming you don't want to filter the list (include all items) you must return true, otherwise false:

if (Equals(whereClause, null))
     whereClause = () => true; 

Notice: The { and } are not necessary if you only return a value with a single statement.

But you should know that the most framework methods don't work in this way. They would throw an ArgumentNullException instead of setting a value.

Koopakiller
  • 2,838
  • 3
  • 32
  • 47
1

Assuming that when whereClause is null you don't want to apply any filter.

        using (var context = new UserDbContext())
        {
            context.Users.Attach(user);
            context.Entry(user).Collection(p => p.Purchases)
            .Query()
            .Where(whereClause ?? p => true)
            .Load();

            if (Equals(user.Purchases, null))
                return new List<Purchases>();
        }
davke
  • 350
  • 1
  • 7