我試圖修改表達式樹用於動態創建一個包含表達式最終導致SQL像理解表達式樹和參數評估
P IN (123, 124, 125, 200, 201)
,而不是檢查執行範圍檢查,最終導致SQL像
(P >= 123 AND P <= 125) OR (P >= 200 AND P <= 201)
我立足於this post我的解決方案。
static public Expression<Func<TElement, bool>>
BuildContainsExpression<TElement, TValue>(
Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
// Removed for post: Input checks and edge cases
var equals =
values.Select(value =>
(Expression)Expression.Equal(valueSelector.Body,
Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) =>
Expression.Or(accumulate, equal));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
我能夠得到檢查工作,如果我提供比較值範圍:
long testValue = 5;
List<KeyValuePair<int, int>> ranges = new List<KeyValuePair<int, int>>()
{
new KeyValuePair<long, long>(3, 6),
new KeyValuePair<long, long>(10, 12),
new KeyValuePair<long, long>(20, 20),
};
List<BinaryExpression> rangeExpressions = new List<BinaryExpression>();
foreach (var pair in ranges)
{
var greaterThanOrEqual =
Expression.GreaterThanOrEqual(Expression.Constant(testValue),
Expression.Constant(pair.Key));
var lessThanOrEqual =
Expression.LessThanOrEqual(Expression.Constant(testValue),
Expression.Constant(pair.Value));
var inRange = Expression.AndAlso(greaterThanOrEqual, lessThanOrEqual);
rangeExpressions.Add(inRange);
}
var final =
rangeExpressions.Aggregate<Expression>((a, b) => Expression.Or(a, b));
var result = Expression.Lambda<Func<bool>>(final).Compile()();
但是,我不能理清如何獲取值從passed-比較在表達式中,當我將該代碼放入與Linq一起使用的方法中時。該方法的簽名是:
Expression<Func<TElement, bool>>
BuildRangeExpression<TElement>(
Expression<Func<TElement, long>> valueSelector,
IEnumerable<long> values)
,它是用來像:
問題
如何評估
Expression<Func<TElement, long>> valueSelector
,這樣我可以使用價值傳遞到BuildRangeExpression
而不是我目前LY硬編碼值
long testValue = 5;
這還不夠,表達式還應該從'valueSelector'訪問屬性。 – svick 2013-02-18 22:29:24