1

条件オブジェクト (プロパティのリストを持つダム オブジェクト) を受け取り、その条件オブジェクトで "CreateExpression" メソッドを呼び出し、返された式を使用して結果をフィルター処理する 2 つの同様のメソッドがあります。

私の例の 1 つは、1 つの基準のみの引数を持ち、問題なく動作します。2 番目の方法では、List<Criteria>and を使用して、リスト内の各基準を反復処理し、その式を生成してから、前の式に "and" します。最終結果は、linq クエリで使用できる 1 つの大きな式になるはずです。

ただし、この 2 番目の方法は機能しません。デバッガーを使用すると、述語が本体とラムダ式で内部的に表示されますが、SQL サーバーにヒットすると、where 句がまったくない select ステートメントだけが送信されます。

機能するメソッドは次のとおりです (1 つの基準オブジェクトを使用):

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()」メソッドを使用する必要がありました。2番目のメソッドの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 に答える