Transform ExpressionVisitor to DbExpressionVisitor, read parameter as constant

170 Views Asked by At

I currently have some ExpressionVisitors I manually use on some IQueryable calls

But I would like to use an interceptor to hook them into all queries, but then I need to transform them to DbExpressionVistors

I think I have them all sorted, except one, which takes a parameter value and outputs it as a constant, to create unique query plans based on a tenant id

The problem I have is that I cant seem to find a way to extract the parameter value from the DbParameterReferenceExpression into a constant value like in the previous code for the ExpressionVisitor:

public class DeParameterizeTenantIdVisitor : ExpressionVisitor
{
    protected override Expression VisitMember(MemberExpression node)
    {
        if (IsTenantType(node))
        {
            var expression = Visit(node.Expression);

            var constantExpression = expression as ConstantExpression;

            var val = GetValue(constantExpression, node.Member);

            if(val != null)
                return Expression.Constant(val);

        }
        return base.VisitMember(node);
    }

    private static bool IsTenantType(Expression node)
    {
        return node.Type == typeof(OrganizationId);
    }

    private static object GetValue(ConstantExpression constantExpression, MemberInfo member)
    {
        if (constantExpression != null)
        {
            var container = constantExpression.Value;

            var info = member as FieldInfo;
            if (info != null)
            {
                var value = info.GetValue(container);
                return value;
            }
            var propertyInfo = member as PropertyInfo;
            if (propertyInfo != null)
            {
                var value = propertyInfo.GetValue(container, null);
                return value;
            }
        }

        return null;
    }
}

Anyone have any input or feedback about it? I have been trying to search around for it but it seems to be very experimental ground I'm onto!

Edit: Or is it possible to use my existing ExpressionVisitior in relation with a interceptor or DbExpressionVisitor?

0

There are 0 best solutions below