我有接受Expression<Func<T, string>>
,例如x => x.Name
,和一個術語,並且返回x => x.Name.Contains(term)
的方法:用鏈式屬性構造表達式樹?
鑑於模型;
class X
{
public Y Y {get; set;}
}
class Y
{
public string Z {get; set;}
}
它非常適用GenerateForMember<Y>(y => y.Z, "foobar")
,但目前並沒有爲GenerateForMember<X>(x => x.Y.Z, "foobar")
工作。它提供了異常
「Z」不是「UserQuery + X」
如何更新我的方法與鏈式性質工作的會員?
方法如下:
protected Expression<Func<T, bool>> GenerateForMember<T>(Expression<Func<T,string>> expression, string term)
{
var type = typeof(T);
var memberExpression = ((expression.Body.NodeType == ExpressionType.Convert)
? ((UnaryExpression)expression.Body).Operand
: expression.Body) as MemberExpression;
ParameterExpression parameter = Expression.Parameter(type, type.Name.ToLower());
MemberExpression member = Expression.PropertyOrField(parameter, memberExpression.Member.Name);
var propertyInfo = memberExpression.Member as PropertyInfo;
var memberType = propertyInfo == null
? ((FieldInfo) memberExpression.Member).FieldType
: propertyInfo.PropertyType;
ConstantExpression constant = Expression.Constant(term, typeof(string));
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var containsMethodExp = Expression.Call(member, method, constant);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameter);
}
我解剖和重建的原因是因爲參數名稱可能不匹配。但是我可以使用我已經在其他地方使用的訪問者對其進行重命名,然後使用您的方法。謝謝。 – Andre
@Andre,我建議的方法重用了原始表達式中的相同參數。 –
@YacoubMassad對不起,我還不夠清楚。調用這個函數的函數可能會接收多個成員和術語,然後加入它們。例如,傳遞'x => x.Foo'和'y => y.Bar'並且術語「foo」,「bar」將導致x =>(x.Foo.Contains(「foo」)|| x .Foo.Contains(「bar」))&&(x.Bar.Contains(「foo」)|| x.Bar.Contains(「bar」))' – Andre