Reputation: 953
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 ?
Upvotes: 1
Views: 954
Reputation: 45947
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.
Upvotes: 3
Reputation: 393
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
Upvotes: 0