1 回答

TA貢獻1780條經驗 獲得超5個贊
我認為你使用活頁夾使事情變得過于復雜。ExpandoObject實現IDictionary<string, object>接口,因此您可以替換x => x.FirstName == "Jonas"為x => x["FirstName"] == "Jonas"哪個應該更容易。另外,您必須重寫VisitLambda, 來修改類型參數,否則轉換將失敗。
這是示例代碼:
public class ReplaceToExpandoVisitor<TSource> : ExpressionVisitor
{
private static readonly PropertyInfo ItemProperty = typeof(IDictionary<string, object>).GetProperty("Item");
private readonly ParameterExpression _targetParameter = Expression.Parameter(typeof(ExpandoObject));
protected override Expression VisitLambda<T>(Expression<T> node)
{
var body = this.Visit(node.Body);
var parameters = node.Parameters.Select(this.Visit).Cast<ParameterExpression>();
return Expression.Lambda(body, parameters);
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node.Type == typeof(TSource))
{
return this._targetParameter;
}
return node;
}
protected override Expression VisitMember(MemberExpression node)
{
if (node.Member.MemberType != MemberTypes.Property)
{
throw new NotSupportedException();
}
string memberName = node.Member.Name;
return Expression.Convert(
Expression.Property(
this.Visit(node.Expression),
ItemProperty,
Expression.Constant(memberName)
),
((PropertyInfo)node.Member).PropertyType
);
}
}
用法:
Expression<Func<MyEntity, bool>> exp = x => x.FirstName == "Jonas";
Expression<Func<ExpandoObject, bool>> exp2 = (Expression<Func<ExpandoObject, bool>>) new ReplaceToExpandoVisitor<MyEntity>().Visit(exp);
dynamic obj = new ExpandoObject();
obj.FirstName = "Jonas";
bool result = exp2.Compile().Invoke(obj);
- 1 回答
- 0 關注
- 164 瀏覽
添加回答
舉報