during runtime, dynamically add numerous linq expressions

c# dynamic-linq entity-framework linq predicatebuilder

Question

I have two similar methods that take a criteria object (dumb object with a list of properties), call a "CreateExpression" method on that criteria object, and then use the returned expression to filter results.

One of my examples has an argument of only one criteria, and it works with no problem. My second method takes a List<Criteria> and then attempts to iterate through each criteria in the list, and generate the expression for it, and then "and" it to the previous expression. The end result is supposed to be one big expression that I can then use in my linq query.

However, this second method is not working. When I use the debugger, I can see the predicate with it's body and lambda expression internally, but when it hits the SQL server, all it sends is a select statement with no where clauses at all.

Here is the method that works (with one criteria object):

public static List<Segment> GetByCriteria(Criteria.SegmentCriteria myCriteria)
        {
            List<Segment> result = null;

            List<Segment> qry = db.Segments.AsExpandable<Segment>().Where<Segment>(CreateCriteriaExpression(myCriteria)).ToList<Segment>();
            qry = qry.Where<Segment>(CreateCriteriaExpressionForCustomProperties(myCriteria).Compile()).ToList<Segment>();


            if (qry != null && qry.Count != 0)
            {
                result = qry;
            }

            return result;
        }

Here is the one that doesn't work:

public static List<Segment> GetByCriteria(List<Criteria.SegmentCriteria> myCriteria, Common.MultipleCriteriaMatchMethod myMatchMethod)
        {

            List<Segment> result = null;

            var predicate = PredicateBuilder.True<Segment>();
            var customPropertiesPredicate = PredicateBuilder.True<Segment>();


            foreach (Criteria.SegmentCriteria x in myCriteria)
            {
                if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAll)
                {
                    predicate = predicate.And(CreateCriteriaExpression(x).Expand());
                    customPropertiesPredicate = customPropertiesPredicate.And(CreateCriteriaExpressionForCustomProperties(x).Expand());
                }
                else if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAny)
                {
                    predicate = predicate.Or(CreateCriteriaExpression(x).Expand());
                    customPropertiesPredicate = customPropertiesPredicate.Or(CreateCriteriaExpressionForCustomProperties(x).Expand());
                }
            }


            List<Segment> qry = db.Segments.AsExpandable<Segment>().Where<Segment>(predicate.Expand()).ToList<Segment>();
            qry = qry.Where<Segment>(customPropertiesPredicate.Expand().Compile()).ToList<Segment>();

            if (qry != null && qry.Count != 0)
            {
                result = qry;
            }

            return result;
        }

I am using Predicate Builder to generate the initial expression. I don't believe there is a problem with those methods since they work with the first (singular) method.

Does anyone know what's going on here?

Edit I forgot to say that the backend is entity framework.

1
1
7/8/2011 5:57:55 PM

Accepted Answer

Ok, I figured it out.

I needed to use the "Expand()" method on ALL places where I was calling a predicate in the lines where I was appending the predicate. Here is the new fixed version of the foreach loop in my second method:

foreach (Criteria.SegmentCriteria x in myCriteria)
            {
                Criteria.SegmentCriteria item = x;
                if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAll)
                {
                    predicate = predicate.Expand().And<Segment>(CreateCriteriaExpression(item).Expand());
                    customPropertiesPredicate = customPropertiesPredicate.Expand().And<Segment>(CreateCriteriaExpressionForCustomProperties(item).Expand());
                }
                else if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAny)
                {
                    predicate = predicate.Expand().Or<Segment>(CreateCriteriaExpression(item).Expand());
                    customPropertiesPredicate = customPropertiesPredicate.Expand().Or<Segment>(CreateCriteriaExpressionForCustomProperties(item).Expand());
                }
            }

And now it works! I found details about this also on this other question.

1
5/23/2017 12:27:01 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow