Kurkula
Kurkula

Reputation: 6762

c# lambda expression if condition inside a where

I have a scenario where I am using lambda expression to filter data by name, address and phone number. But when one property has no value then my filter considers where property is null and it give wrong results. Is there any option to remove a where condition out of three cases with a if condition if property is null. I mean is there any case to add where/check only for object where properties having values?

var filterCriteria ={
name: "abc",
address:"",
phone:""
}

var Details = _context.LogEntities
                    .Where(p => p.name == (filterCriteria.name))
                    .Where(p => p.address== (filterCriteria.address))
                    .Where(p => p.phone== (filterCriteria.phone))

                return Json(Details);

Upvotes: 3

Views: 2156

Answers (3)

koryakinp
koryakinp

Reputation: 4125

You can write an extension method to conditionally apply the filter:

public static IQueryable<T> WhereIf<T>(
   this IQueryable<T> source, bool condition, 
   Expression<Func<T, bool>> predicate)
{
    if (condition)
        return source.Where(predicate);
    else
        return source;
}

And your query becomes:

using static System.String;

...

var employees = _context
   .LogEntities
   .WhereIf(!IsNullOrEmpty(filterCriteria.name), e => e.name == filterCriteria.name)
   .WhereIf(!IsNullOrEmpty(filterCriteria.address), e => e.address == filterCriteria.address)
   .WhereIf(!IsNullOrEmpty(filterCriteria.phone), e => e.phone == filterCriteria.phone)
   .ToList();

Upvotes: 3

ragyaiddo
ragyaiddo

Reputation: 162

When doing filtering, if what you want is to consider null properties in the filter to match any values in the corresponding property in the collection, you should check the null against the filter property, not on the collection item's property. So for a collection like

var myCollection = [
{name: "abc",address:"qwerty",phone:"123"},
{name: "abc",address:"xyz",phone:"456"},
{name: "efg",address:"cde",phone:"654"}]

and filter like

var filterCriteria ={name: "abc",address:"",phone:""}

with desired result like:

[{name: "abc",address:"qwerty",phone:"123"},
{name: "abc",address:"xyz",phone:"456"}]

Your code should be

var Details = _context.LogEntities
                .Where(p => (filterCriteria.name) == null || p.name == (filterCriteria.name))
                .Where(p => (filterCriteria.address) == null || p.address== (filterCriteria.address))
                .Where(p => (filterCriteria.phone) == null || p.phone== (filterCriteria.phone))

Upvotes: 1

Alex Wiese
Alex Wiese

Reputation: 8370

If you still want to return records when the name, address, or phone are null then just check for null in the condition.

var Details = _context.LogEntities
                    .Where(p => p.name == null || p.name == (filterCriteria.name))
                    .Where(p => p.address == null || p.address == (filterCriteria.address))
                    .Where(p => p.phone == null || p.phone == (filterCriteria.phone))

                return Json(Details);

Upvotes: 5

Related Questions