4

搜索了很长一段时间后,我仍然没有找到我正在寻找的答案。我找到了有关从树中添加和删除参数的答案,但没有找到有关替换特定参数的任何答案。

我的第一个方法按我的意愿工作,我需要用 Uri 转义值替换 partitionKey 值,然后返回未转义的结果。

public override IList<T> GetRowEntityList(string partitionKey)
{
    IList<T> rowEntities =  base.GetRowEntityList(Uri.EscapeDataString(partitionKey));
    return rowEntities.Select(UnEscapeRowEntity).ToList();
}

我遇到的问题是重写此方法以使其行为相同。我已经知道该类型T具有属性PartitionKeyRowKey但也可以具有任何其他数量的属性。

对于示例谓词:

x => x.RowKey == "foo/bar" && x.SomeValue == "test" 

我希望它成为

x => x.RowKey == Uri.EscapeDataString("foo/bar") && x.SomeValue == "test"  

有没有办法做到这一点?

T我的基类使用此谓词对包含使用Where(predicate)调用的实体类型的表进行表查找

public override IList<T> GetRowEntityList(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
    //modify predicate value here

    return base.GetRowEntityList(predicate);
}
4

1 回答 1

2

您需要实现一个ExpressionVisitor

class MyVisitor : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
        if(CheckForMatch(node.Left))
            return Expression.Equal(node.Left, Rewrite(node.Right));

        if(CheckForMatch(node.Right))
            return Expression.Equal(Rewrite(node.Left), node.Right);

        return Expression.MakeBinary(node.NodeType, Visit(node.Left), Visit(node.Right));
    }

    private bool CheckForMatch(Expression e)
    {
        MemberExpression me = e as MemberExpression;
        if(me == null)
            return false;

        if(me.Member.Name == "RowKey" || me.Member.Name == "PartitionKey")
            return true;
        else
            return false;
    }

    private Expression Rewrite(Expression e)
    {
        MethodInfo mi = typeof(Uri).GetMethod("EscapeDataString");

        return Expression.Call(mi, e);
    }
}

我认为这是对的。测试有点难。请注意,这仅适用于(x => x.RowKey == "some string"). 它不会为(x => x.RowKey.Equals("somestring"). 它也不会为(x => x.RowKey() == "some string").

然后使用实现的访问者重写谓词:

Expression<Func<T, bool>> predicate = (s => s.RowKey == "1 2");

ExpressionVisitor v = new MyVisitor();
Expression<Func<T, bool>> rewrittenPredicate = v.Visit(predicate);

//rewrittenPredicate then tests if s.RowKey == "1%202"
于 2013-04-09T19:50:51.073 回答