4

私の前の質問に従って: Pulling Apart Expression<Func<T, object>>- もう少し高度なものにしようとしています。現在、私はこれを行うことができます:

var matchingPeople = Connection.Get<Person>(p => p.MarketId == marketId);

これはDapperExtensionsFieldPredicateに変換されます:

// Assume I've successfully parsed p => p.MarketId == marketId into its constituent parts:
// left = p => p.MarketId, theOperator = Operator.Eq, right = marketId
Predicates.Field(left, theOperator, right);

私は今、これを行うことができるようにしたい:

var matchingPeople = Connection.Get<Person>(p => p.MarketId == marketId && p.FirstName == "John" || p.FirstName == "Jack");

次のような SQL を生成します。

DECLARE @MarketId INT = 3
DECLARE @FirstName01 VARCHAR(MAX) = 'John'
DECLARE @FirstName02 VARCHAR(MAX) = 'Jack'

SELECT *
FROM Person
WHERE MarketId = @MarketId AND (FirstName = @FirstName01 OR FirstName = @FirstName02)

DapperExtensionsCompound Predicate Groupsを使用して:

// ** This is the code I am trying to dynamically create based on the lambda that is passed in **

var predicateGroupAnd = new PredicateGroup {Operator = GroupOperator.And, Predicates = new List<IPredicate>()};
// I already have the code to determine: left = p => p.MarketId, theOperator = Operator.Eq, right = marketId
predicateGroupAnd.Predicates.Add(Predicates.Field(left, Operator.Eq, right));

var predicateGroupOr = new PredicateGroup {Operator = GroupOperator.Or, Predicates = new List<IPredicate>()};
// I already have the code to determine: left = p => p.FirstName, theOperator = Operator.Eq, right = "John"
predicateGroupAnd.Predicates.Add(Predicates.Field(left, Operator.Eq, right));
// I already have the code to determine: left = p => p.FirstName, theOperator = Operator.Eq, right = "Jack"
predicateGroupOr.Predicates.Add(Predicates.Field(left, Operator.Eq, right));

var predicateGroupAll = new PredicateGroup // This is what will be passed to DapperExtensions' GetList<T> method
    {
        Operator = GroupOperator.And, // How do I set this correctly?
        Predicates = new List<IPredicate> {predicateGroupAnd, predicateGroupOr}
    };

私の問題は、式ツリーの解析方法にあるようです。次のラムダ式があるとします。

p => p.MarketId == marketId && p.FirstName == "John" || p.FirstName == "Jack"

これを にキャストできBinaryExpressionます。を使用するBinaryExpression.Leftと、

p.MarketId == marketId && p.FirstName == "John"

BinaryExpression.Right利回り:

p.FirstName == "Jack"

また、NodeTypeオーバーオールBinaryExpressionの は、ラムダの最後の条件演算子に設定されているようです。ExpressionType.OrElse

再帰を使用してラムダ式を右から左にトラバースする必要があるように感じますが、必要な複合グループ述語を作成できませんでした。AND具体的には、ラムダをグループ化し、ラムダをグループ化するにはどうすればよいORですか? ありがとう!

4

1 に答える 1