我是表達式Tree的新手,我需要將下面的lambda轉換為Expression Tree
Data.Where(s => s.Property.ToString().StartsWith("My Search Data"));
不過我做得很好
Data.Where(s => s.Property.StartsWith("My Search Data");
現在我需要在使用StartsWith之前使用ToString方法。
下面是我的示例代碼。
ParameterExpression e = Expression.Parameter(typeof(T), "e");
PropertyInfo propertyInfo = typeof(T).GetProperty(field);
MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);
ConstantExpression c = Expression.Constant(data, typeof(string));
MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
Expression call = Expression.Call(m, mi, c);
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, e);
query = query.Where(lambda);
想法是你必須從System.Object獲取“ToString”方法。因為它是一個虛方法,運行時可以在真實對像上調度調用。
注意:IData是具有名為“Property”的屬性的任何數據。
ParameterExpression e = Expression.Parameter(typeof(IData), "e");
PropertyInfo propertyInfo = typeof(IData).GetProperty("Property");
MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);
var toString = typeof (Object).GetMethod("ToString");
ConstantExpression c = Expression.Constant(data, typeof(string));
MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
var toStringValue = Expression.Call(m, toString);
Expression call = Expression.Call(toStringValue, mi, c);
Expression<Func<IData, bool>> lambda = Expression.Lambda<Func<IData, bool>>(call, e);
考慮使用允許您通過名稱訪問成員的重載。這將使這更容易做到。
// Data.Where(s => s.Property.ToString().StartsWith("My Search Data"));
var property = "Property";
var filter = "My Search Data";
var param = Expression.Parameter(typeof(T));
var body = Expression.Call(
Expression.Call(
Expression.Property(param, property),
"ToString",
null
),
"StartsWith",
null,
Expression.Constant(filter)
);
var lambda = Expression.Lambda<Func<T, bool>>(body, param);