0

I have an expression tree built like this

Expression<Func<User, bool>> match = o =>
o.Name == viewModel.Name
&& orders.Contains(o.User.Company.CompanyId.ToString())
&& o.dept == viewModel.dept

I only want to include the line

o.dept == viewModel.dept 

when viewModel.dept is 1, 2 or 3 and not include this condition in the expression tree, if it’s any other value.

This code is in a function that gets a viewModel as parameter and the values in the viewModel are used to query the EF model User.

Currently I have 2 separate expression trees to meet this scenario. Is there any better solution?

Thank you

Pravi
  • 77
  • 1
  • 8
  • 1
    Separate expressions, i.e. separate `Where()` calls is _the_ way to do it. Messing with the expression tree would be a lot more complicated and wouldn’t really give you a benefit. – poke Apr 16 '19 at 11:16
  • Maybe : [Linq: adding conditions to the where clause conditionally](https://stackoverflow.com/questions/10884651/linq-adding-conditions-to-the-where-clause-conditionally) – xdtTransform Apr 16 '19 at 11:18
  • 1
    `(viewModel.dept == 1 || viewModel.dept == 2 || viewModel.dept == 3) && o.dept == viewModel.dept ` does not work? – taquion Apr 16 '19 at 11:18
  • @taquion, apologies it didn't work and I am still using 2 different expressions.. – Pravi Apr 16 '19 at 13:04
  • @poke, can you point us to some example for it.. in the end, I need to return expression of type Expression>.. cheers – Pravi Apr 16 '19 at 13:06
  • @Pravi The question linked by Servy does show some examples. Basically, just store the result from calling `Where()`, and then conditionally call `Where()` on that result again. – poke Apr 16 '19 at 16:50

1 Answers1

0

I finally got a graceful solution using LINQKit (https://github.com/scottksmith95/LINQKit) and its PredicateBuilder This is what I did.

var match = PredicateBuilder.New<User>(true);
match = match.And(o => o.Name == viewModel.Name);
match = match.And(o =>orders.Contains(o.User.Company.CompanyId.ToString()));
if(viewModel.dept==1 || viewModel.dept == 2 || viewModel.dept==3)
{
    match = match.And(o=>o.dept == viewModel.dept);
}

return match;
Pravi
  • 77
  • 1
  • 8
  • No need to use the predicate builder to AND the first two conditions together. Just add them in a single expression. – Servy Apr 16 '19 at 14:37
  • @servy, correct, its a simple condition here, but, if the condition is complex than, its better to follow this approach.. – Pravi Apr 16 '19 at 15:11
  • It doesn't matter how simpler or complex the condition is. All that really matters is whether you are composing them dynamically or not, and you're not. – Servy Apr 16 '19 at 15:28