從昨天起我一直在教自己表達樹 ,我在比較兩個字符串值時遇到了問題。我已經使這個測試用例失敗並出現錯誤:
No method 'Compare' on type 'System.String' is compatible with the supplied arguments.
left = Expression.Call(
運行時失敗left = Expression.Call(
Type type = typeof(string);
Expression left, right;
left = Expression.Constant("1", type);
right = Expression.Constant("2", type);
// fails at run-time on the next statement
left = Expression.Call(
typeof(string),
"Compare",
new Type[] { type, type },
new Expression[] { left, right });
right = Expression.Constant(0, typeof(int));
我將在Expression.Equal, LessThan, LessThanOrEqual, GreaterThan or GreaterThanOrEqual
使用結果左右。這就是Compare方法的原因。
我確信這很簡單,我已將我的代碼簡化為這個簡單的測試用例。誰知道我哪裡出錯了?
這是Expression.Call
代碼中的問題:
new Type[] { type, type },
那是試圖調用string.Compare<string, string>
- 它們是泛型參數 ,而不是普通參數的類型。鑑於它是非泛型方法,只需在此處使用null。
簡短但完整的計劃:
using System;
using System.Linq.Expressions;
class Test
{
static void Main()
{
var left = Expression.Constant("1", typeof(string));
var right = Expression.Constant("2", typeof(string));
var compare = Expression.Call(typeof(string),
"Compare",
null,
new[] { left, right });
var compiled = Expression.Lambda<Func<int>>(compare).Compile();
Console.WriteLine(compiled());
}
}
我試圖做一個類似於lambda where子句( LINQ to SQL ),並且因為各種搜索讓我登陸這個頁面,所以我將在這里分享這樣一個解決方案,以防它幫助其他人降落在這裡。
當您使用Compare的通用表達式簡化您正在執行的操作時,這是最簡單的 。
public static Expression CompareLessThanOrEqualTo(Expression e1, Expression e2)
{
var compare = Expression.Call(typeof(string),
"Compare",
null,
new[] { e1, e2 });
return Expression.LessThanOrEqual(compare, Expression.Constant(0));
}
然後就像其他任何人一樣使用這個表達式
public static Expression<Func<TypeOfParent, bool>> PropertyLessThanOrEqualString<TypeOfParent, String>(PropertyInfo property, String value)
{
var parent = Expression.Parameter(typeof(TypeOfParent));
var expressionBody = CompareLessThanOrEqualTo(Expression.Property(parent, property), Expression.Constant(value));
return Expression.Lambda<Func<TypeOfParent, bool>>(expressionBody, parent);
}
巫婆可以使用如
public static IQueryable<T> ApplyFilters<T>(this IQueryable<T> query, List<GridFilters> gridFilters)
{
// foreach filter
// Get property (propertyInfo)
// Get Value(s)
// Apply Filter
query = query.Where(PropertyLessThanOrEqualString<T, string>(propertyInfo, value1));
// ...
return query;
}
如果您有一個需要應用的用戶選擇的過濾器列表,則可以選擇值和運算符。 (開頭,包含,範圍之間)