1

我有两个类似的方法,它们采用标准对象(具有属性列表的哑对象),在该标准对象上调用“CreateExpression”方法,然后使用返回的表达式来过滤结果。

我的一个例子只有一个标准的论点,它没有问题。我的第二种方法采用 aList<Criteria>然后尝试遍历列表中的每个条件,并为其生成表达式,然后将其“和”到前一个表达式。最终结果应该是一个大表达式,然后我可以在我的 linq 查询中使用它。

但是,这第二种方法不起作用。当我使用调试器时,我可以在内部看到谓词及其主体和 lambda 表达式,但是当它到达 SQL 服务器时,它发送的只是一个完全没有 where 子句的 select 语句。

这是有效的方法(使用一个标准对象):

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;
        }

这是一个不起作用的:

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;
        }

我正在使用Predicate Builder来生成初始表达式。我不相信这些方法有问题,因为它们适用于第一种(单一)方法。

有谁知道这里发生了什么?

编辑 我忘了说后端是实体框架。

4

1 回答 1

1

好的,我想通了。

我需要在我附加谓词的行中调用谓词的所有地方使用“Expand()”方法。这是我的第二种方法中 foreach 循环的新固定版本:

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());
                }
            }

现在它起作用了!我在另一个问题上也找到了有关此的详细信息。

于 2011-07-08T19:28:38.907 回答