tags:

views:

32

answers:

3

I have a pretty complex linq statement I need to access for different methods. Each of these methods may need to see the resulting data with different parameters. For one method it may be a project code, for another it may be language. The statement is pretty much the same it's just the where part which changes.

I have not been able to figure out how to use different where statements without duplicating the entire linq statement, and that just isn't dry enough for me.

For example (greatly simplified):

var r = from c in  customer
        where c.name == "some name"

// or it may be 

var r = from c in customer
        where c.customerId == 8

Is there a way to have both of these in the same statement so I can use one or the other based on what I am doing? I tried an if statement to use one of the where statements or the other, and that didn't go over very well.

+3  A: 

You can do it like this:

var r = from c in customer
        select c;

if (CustomerName != null)
  r = r.Where(c => c.name == CustomerName);
if (CustomerID != null)
  r = r.Where(c => c.customerId == CustomerID);

You could make these else if if only one should apply, in my example any criteria that wasn't null would be applied to the query to filter on.

Nick Craver
You might be able to simply assign `customer` to r depending on it's type or even reassign the results of the Where clause to customer. It depends on context. For example, if Customers is Table<Customer>, I think that you could simply do `var r = db.Customers.AsQueryable()`, then r would be `IQueryable<Customer>`
tvanfosson
@tvanfosson - Agreed, if it's a simple query like that, best to use that approach...sounded from the question like it wasn't. I think in your example just `var r = db.Customers` works though, since `Table<T> : IQueryable<T>`
Nick Craver
The linq statement is complicated, though the only difference between the two or three iterations is where statement.
Brettski
Is this a 'better' approach then Hueso Azul's?
Brettski
@Brettski - I would say so...when you add more where cases it only gets messier, this method keeps it pretty sane even in that case, easier to read as well I think... personal preference though, do what's most readable/maintainable for **you**.
Nick Craver
@nick, I think `IQueryable<Customer> r = db.Customers` will work, but not `var r = ...` because you are reasssigning `r` later. If you use `var` then I think `r` becomes `Table<Customer>`, not `IQueryable<Customer>` and you can't assign an `IQueryable<Customer>` (result of the Where clause) to a `Table<Customer>` because the inheritance relationship goes the other way.
tvanfosson
@tvanfosson - Good point, I've been working in F# today where the var rules are different, you're absolutely right.
Nick Craver
Thank you everyone
Brettski
A: 

You can pass in a Func delegate to your function (the Where clause takes a Func delegate with a boolean return type). Then use this delegate in the Where clause.

Oded
+1  A: 

what about something like this?

var useIdForFiltering = false;

var r = from c in customer
    where (useIdForFiltering && c.customerId == 8) || (c.name == "some name")
Hueso Azul
That's an interesting approach, thank you.
Brettski