1

I have an MVC5 project. On my page I have 4 checkboxes and a search button. When the button is clicked, an ajax call is triggered to call the function below:

[HttpPost]
public ActionResult GetOpenOrders(ProductionStatus pStatus)
{
    List<vw_orders> orderList = new List<vw_orders>();

    OrderRepository orderRepo = new OrderRepository();

    // Get the total list of open orders
    orderList = orderRepo.getAllByStatus("V");

    // If not all values are 0, we have to filter
    // (allZero is a private function that checks if all property values of pStatus are 0)
    if(allZero(productieStatus) != true)
    {
        // Only use the properties of pStatus where
        // the value is 1
        // example: pStatus.A = 1, pStatus.B = 0, pStatus.C = 1
        orderList = orderList.Where( p => if(pStatus.A == 1) p.a == pStatus.A || if(pStatus.B == 1) p.b == pStatus.B || if(pStatus.C == 1) p.c = pStatus.C);

    }

    // return some json of orderList.ToList()
}  

How can I add the OR condition conditionally to my WHERE clause, thus only when value of pStatus.property == 1 ?

kwv84
  • 943
  • 3
  • 11
  • 25
  • Please check this link http://stackoverflow.com/questions/3682835/if-condition-in-linq-where-clause – Dhananjay Singh Apr 03 '17 at 12:58
  • Take a look at this [PredicateBuilder](http://ctrlcvprogrammer.blogspot.de/2014/11/implement-predicate-builder-to.html) implementation. Now you just have to apply some simple reflection logic to iterate all properties of `ProductionStatus` and find out which propertie is `== 1` and append a new `Or` clause to your predicate. – ckruczek Apr 03 '17 at 13:09

2 Answers2

3

replace

orderList = orderList.Where(p => if(pStatus.A == 1) p.a == pStatus.A || if(pStatus.B == 1) p.b == pStatus.B || if(pStatus.C == 1) p.c = pStatus.C)

with

orderList = orderList.Where(p => (pStatus.A == 1 && p.a == pStatus.A) ||
                                 (pStatus.B == 1 && p.b == pStatus.B) || 
                                 (pStatus.C == 1 && p.c == pStatus.C))

thus only when value of pStatus.property == 1

so p.a == pStatus.A and for pStatus.A == 1 need to be true to make this row part of the result.

fubo
  • 44,811
  • 17
  • 103
  • 137
  • I don't think that's what he wants to do. It seems like if `(pStatus.A == 1)` then he wants to set `p.a == pStatus.A` – Christopher Lake Apr 03 '17 at 12:48
  • `==` isn't settin, it's comparing – fubo Apr 03 '17 at 12:49
  • don't think this is what OP looking for...per post only for `pStatus.some_property == 1` add another `OR` condition – Rahul Apr 03 '17 at 12:51
  • The conversion here is not equivalent. Since if `pStatus.A` is **not** equal to `1`, the `.. & ..` will return `false` whereas it should be `true` (the `if` does not "fire"). – Willem Van Onsem Apr 03 '17 at 13:03
0

If I understand your question correctly, you want to check the value of a property iff the respective property is set in the pStatus object.

This is simply, if pStatus.A == 1 then p.A == pStatus.A must be true. The problem with this statement is that we have to check the first part pStatus.A == 1, and then determine if we need to check the second part p.A == pStatus.A; which, we want to avoid having too many conditional checks within our linq statement since things can quickly get messy. So let's try to reduce what you are really checking for.

An easy way to show this is statement is as X=>Z(if X then Z), where X = pStatus.A == 1 and Z = p.A == pStatus.A. X=>Z is logically equivalent to ¬X v Z (not X or Z), because if X is not true we don't care what Z is and if Z is true then we don't care if X is true. In your situation, if pStatus.A != 1 then it doesn't matter what p.A is equal to, and if p.A == pStatus.A then it doesn't matter if pStatus.A == 1 or not because in either case the check will pass.

Now, if we substitute back in your checks for X and Z we get (!(pStatus.A == 1) || p.A == pStatus.A) which we can move the not inside the parenthesis and get (pStatus.A != 1 || p.A == pStatus.A).

If we substitute this equivilant statement in for the checks we get:

orderList = orderList.Where( p => (pStatus.A != 1 || p.A == pStatus.A) && (pStatus.B != 1 || p.B == pStatus.B) && (pStatus.C != 1 || p.C == pStatus.C);

We use && between the groups because we want each check to have to pass

Lithium
  • 373
  • 7
  • 21