1

I've been experimenting with LINQ to SQL recently and have a quick question. The basic premise is I have a search request which contains a Make and Model which I use to search a DB containing cars.

The expression for my Where Clause is shown below:

.Where(c => c.make == search.make  && c.model == search.model)

This is fine when my search contains both a make and a model. The problem arises when it only contains a make(or vice versa) and not both search fields. I want it to return all cars of that make, it is however returning none.

Im assuming this is because it is looking for the make plus a model that is null or empty?

Is there an elegant way to get around this other than manually building up the query with a series of "if not null append to query" type steps?

Boob
  • 1,023
  • 4
  • 13
  • 20
  • That would interest me too, now i solved this kind of problem with an If Else and then in the both cases i execute a different Linq to Sql query. – BigL Sep 23 '11 at 10:53

8 Answers8

3

Have you tried:

.Where(c => (search.make == null || c.make == search.make)  && (search.model == null || c.model == search.model))

Update: There's actually a nice treatment of the general problem, and clean solutions, here: LINQ to SQL Where Clause Optional Criteria. The consensus seems to be that an extension method is cleanest.

Community
  • 1
  • 1
Tao
  • 13,457
  • 7
  • 65
  • 76
  • Thanks, this makes sense. I knew there would be a better way, just didnt jump out at me...it's been a long week :) – Boob Sep 23 '11 at 11:05
2
.Where(c => (search.make == null || c.make == search.make) && 
            (search.model == null || c.model == search.model))
Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
1

IMO, split it:

IQueryable<Car> query = ...
if(!string.IsNullOrEmpty(search.make))
    query = query.Where(c => c.make == search.make);
if(!string.IsNullOrEmpty(search.model))
    query = query.Where(c => c.model== search.model);

This produces the most appropriate TSQL, in that it won't include redundant WHERE clauses or additional parameters, allowing the RDBMS to optimise (separately) the "make", "model" and "make and model" queries.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

This should work.

.Where(c => 
    (search.make == null || c.make == search.make) &&
    (search.model == null || c.model == search.model))
Chris Snowden
  • 4,982
  • 1
  • 25
  • 34
0

you could write something like this:

.Where(c => c.make == search.make ?? c.make && c.model == search.model ?? c.model)
Paulo Santos
  • 11,285
  • 4
  • 39
  • 65
  • Thanks Paulo, can you explain what's happening here? I'm quite new to LINQ and LAMBDA stuff, haven't seen the "??" syntax used before? – Boob Sep 23 '11 at 11:09
  • The `??` is the coalesce operator. If the value on the left side is null it will use the value on the right side. It's equivalent to `(x == null ? y : x)` – Paulo Santos Sep 23 '11 at 11:20
0
.Where(c => (string.IsNullOrEmpty(c.make) || c.make == search.make) && 
            (string.IsNullOrEmpty(c.model) || c.model == search.model))
alexl
  • 6,841
  • 3
  • 24
  • 29
0
.Where(c => (string.IsNullOrEmpty(search.make) || c.make == search.make) &&
            (string.IsNullOrEmpty(search.model) || c.model == search.model))

That's assuming the properties are strings.

AndrewC
  • 6,680
  • 13
  • 43
  • 71
  • Actually, on re-reading the question it's probably not even necessary to call IsNullOrEmpty. Depends how you're creating your search object. – AndrewC Sep 23 '11 at 10:58
0
Where(c => (search.make == null || c.make == search.make) && 
           (search.model == null || c.model == search.model))
slawekwin
  • 6,270
  • 1
  • 44
  • 57