score:2

Accepted answer

another option is to do the null check outside of the query

var initialquery = db.tblproperties;
if(smodel.statusid != null)
{
    initialquery = initialquery.where(p => smodel.statusid.contains(p.propertylocation));
}
var query = initialquery.tolist();

or as a helper method

public static ienumerable<t> conditionalwhere<t>(
    this ienumerable<t> collection, 
    func<bool> condition, 
    expression<func<t, bool>> predicate)
{
    if(condition())
        return collection.where(predicate);
    return collection;
}

and then

var query = db.tblproperties.conditionalwhere( 
    () => smodel.statusid != null,
    p => smodel.statusid.contains(p.propertylocation));

and you can chain them together

var query = db.tblproperties.conditionalwhere( 
        () => smodel.statusid != null,
        p => smodel.statusid.contains(p.propertylocation))
    .conditionalwhere( 
        () => someothercollection != null,
        p => someothercollection.contains(p.propertylocation));

this will avoid running whatever the condition is multiple times for linq-to-objects and will allow you to use something that cannot be translated to sql for ef or linq-to-sql.

score:1

you can simply add a null check in your where clause:

 var query=db.tblproperties.where(p => smodel.statusid == null || smodel.statusid.contains(p.propertylocation))
                           .select(x=>x).tolist();

score:1

c# uses short-circuit evaluation of boolean expressions. this means that c# stops evaluating an expression as soon as its result can be determined.

for instance in a && b, the result is known to be false if a is false, so b will not be evaluated. in a || b the result is known to be true if a is true, so b will not be evaluated.

you can use this to protect you from an exception by adding a null-test:

var query = db.tblproperties
    .where(p => smodel.statusid == null || 
                smodel.statusid.contains(p.propertylocation))
    .tolist();

you can also drop the .select(x=>x) part as it is doing nothing.


if you are using linq to ef then the text above does not apply. you cannot perform a null check on a collection, as this cannot translate to sql. instead make the check before:

bool ignore = smodel.statusid == null || !smodel.statusid.any();
var query = db.tblproperties
    .where(p => ignore || 
                smodel.statusid.contains(p.propertylocation))
    .tolist();

score:2

so if smodel.statusid is null, you want to return all the records?

var query=db.tblproperties.where(p => smodel.statusid == null || smodel.statusid.contains(p.propertylocation))
                          .select(x=>x).tolist();

so if you look at the where clause now, if smodel.statusid == null then every item will pass the where clause. note that the .contains won't be called because of short cutting (if the first term of an or is true, there's no point evaluating the second, so it won't).

you might also consider doing something like this:

.where(p => smodel.statusid == null || 
            !smodel.statusid.any() || 
            smodel.statusid.contains(p.propertylocation))

that way you are checking both that statusid is not null and that the collection statusid isn't empty.

if you can make statusid default to an empty collection instead of null (for example, set it in the constructor of whatever class smodel is), then you can do this:

.where(p => !smodel.statusid.any() || 
        smodel.statusid.contains(p.propertylocation))

since you won't need the null check anymore and any should be translatable into linq to sql.

score:3

posted answers are correct and gave you the solution you need, i will go with checking for null, if you need this behavior in couple of places. if this request is repetitive in many places, i will go with the below solution.

there is another, more cleaner way if you're doing a lot of this checking, will be to add extension methods to do it for you.

extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. for client code written in c# and visual basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

code:

public static class collectionextension
{
    public static bool checkcontainsifhasvalue<t>(this ienumerable<t> source, t value)
    {
        return source == null || source.contains(value);
    }
}

usage:

var query = db.tblproperties
            .where(p => smodel.statusid.checkcontainsifhasvalue(p.propertylocation))
            .tolist();

Related Query

More Query from same tag