私の前の質問に従って: 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
ですか? ありがとう!