Reputation: 262
I am trying to use LinqKit's PredicateBuilder
to create some nested logic to compare against SQL, and this works fine when I manually specify the conditions, but when I place the code in a loop I get an ArgumentOutOfRangeException
later on when I try to query based on the predicate I built. Here is my code:
var outerPredicate = PredicateBuilder.New<DataRow>();
var innerPredicate = PredicateBuilder.New<DataRow>();
for (int i = 0; i < 4; i++)
{
innerPredicate = PredicateBuilder.New<DataRow>();
for (int j = 0; j < 1; j++)
{
innerPredicate = innerPredicate.Or(y => y.Field<string>(sqlNames[i]) == filters[i][j]);
}
outerPredicate = outerPredicate.And(innerPredicate);
}
This code always produces the same ArgumentOutOfRangeException
, even if I set each loop to run only once, but this code runs perfectly:
var outerPredicate = PredicateBuilder.New<DataRow>();
var innerPredicate = PredicateBuilder.New<DataRow>();
innerPredicate = innerPredicate.Or(y => y.Field<string>(sqlNames[3]) == filters[3][0]);
innerPredicate = outerPredicate.And(innerPredicate);
innerPredicate = PredicateBuilder.New<DataRow>();
innerPredicate = innerPredicate.Or(y => y.Field<string>(sqlNames[2]) == filters[2][0]);
outerPredicate = outerPredicate.And(innerPredicate);
innerPredicate = PredicateBuilder.New<DataRow>();
innerPredicate = innerPredicate.Or(y => y.Field<string>(sqlNames[1]) == filters[1][0]);
outerPredicate = outerPredicate.And(innerPredicate);
innerPredicate = PredicateBuilder.New<DataRow>();
innerPredicate = innerPredicate.Or(y => y.Field<string>(sqlNames[0]) == filters[0][0]);
outerPredicate = outerPredicate.And(innerPredicate);
As far as I can tell, these two pieces of code are functionally identical. I would greatly appreciate anyone who can solve this mystery for me.
Upvotes: 1
Views: 63
Reputation: 1705
This should do it:
var outerPredicate = PredicateBuilder.New<DataRow>();
var innerPredicate = PredicateBuilder.New<DataRow>();
for (int i = 0; i < 4; i++)
{
innerPredicate = PredicateBuilder.New<DataRow>();
for (int j = 0; j < 1; j++)
{
var ii=i;var jj=j;
innerPredicate = innerPredicate.Or(y => y.Field<string>(sqlNames[ii]) == filters[ii][jj]);
}
outerPredicate = outerPredicate.And(innerPredicate);
}
see: Captured variable in a loop in C#
Upvotes: 2