user3140169
user3140169

Reputation: 221

PredicateBuilder Contains breaks when value is null

It appears that my LinqKit Predicatebuilder function breaks when either the FirstName or LastName value = null.

public partial class Student
{
    public int id { get; set; } // PK
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

private Expression<Func<Student, bool>> BuildDynamicWhereClause(string searchValue)
{
    // simple method to dynamically plugin a where clause
    var predicate = PredicateBuilder.New<Student>(true); // true -where(true) return all

    if (String.IsNullOrWhiteSpace(searchValue) == false)
    {
        var searchTerms = searchValue.Split(' ').ToList().ConvertAll(x => x.ToLower());

        predicate = predicate.Or(s => searchTerms.Any(srch => s.FirstName.Contains(srch)));
        predicate = predicate.Or(s => searchTerms.Any(srch => s.LastName.Contains(srch)));
    }
    return predicate;
}

How do I rewrite predicate.Or(s => searchTerms.Any(srch => s.FirstName.Contains(srch))); since Contains requires a value to search and throws an exception?

I've tried:

predicate = predicate.Or(s => searchTerms.Any(srch => s.FirstName == null ? false : s.FirstName.Contains(srch)));

and also

predicate = predicate.Or(s => searchTerms.Any(srch => s.FirstName == null ? true : s.FirstName.Contains(srch)));

which compiles but now the FirstName is not searched.

Upvotes: 0

Views: 1178

Answers (1)

Zer0
Zer0

Reputation: 7354

Use the null conditional operator. This code only calls Contains if FirstName is not null, avoiding the exception.

searchTerms.Any(srch => s.FirstName?.Contains(srch) == true));

The explicit == true is necessary as this evaluates to a bool? and not a bool.

For LINQ providers that don't support this operator it's effectively the same as

searchTerms.Any(srch => s.FirstName == null ? false : s.FirstName.Contains(srch));

Upvotes: 1

Related Questions