1

Looking for ways to find participation in queryable Joins...

Basically, I want to check if model class X is used in join operations in Queryable statements. Using David Fowl's QueryInterceptor I can put an expression visitor on an IQueryable. Then check for Lambda expressions (looks like joins are represented with them generally) for parameters with a type of class X. The visitor can toggle a flag for a hit.

Other ways? Again, I am only interested in if class X is involved in joins.

4

1 回答 1

1

您可以使用 ExpressionVisitor 类来检查表达式树并提取连接的通用类型。

在静态构造函数中,我们将使用反射来查找 Queryable 类上 Join 的方法信息。在方法调用中,我们将查看调用方法是否是通用的,以及它是否与 Queryable 类上的 Join 方法匹配。如果是这样,我们知道前两个通用参数是外部类型和内部类型。将它们添加到哈希集中只是为了删除任何重复项。

public class JoinVisitor : ExpressionVisitor
{
    private static readonly MemberInfo[] _joinMethods;

    private ICollection<Type> Types = new HashSet<Type>();

    static JoinVisitor()
    {
        _joinMethods =
            typeof (Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => m.Name == "Join").ToArray();

    }

    // make use of GetJoinTypes to create class
    private JoinVisitor()
    {

    }

    public static IEnumerable<Type> GetJoinTypes(System.Linq.Expressions.Expression expression)
    {
        var joinVisitor = new JoinVisitor();
        joinVisitor.Visit(expression);
        return joinVisitor.Types;
    }

    protected override System.Linq.Expressions.Expression VisitMethodCall(MethodCallExpression node)
    {
        if (node.Method.IsGenericMethod && _joinMethods.Contains(node.Method.GetGenericMethodDefinition()))
        {
            var args = node.Method.GetGenericArguments();
            Types.Add(args[0]);
            Types.Add(args[1]);
        }
        return base.VisitMethodCall(node);
    }
}

可以像这样使用

IQueryable queryable ;  // your IQueryable 
var types = JoinVisitor.GetJoinTypes(queryable.Expression);

然后使用可以只使用 contains 方法来查看类型是否在连接中。您也可以将其更改为传入类型 GetJoinTypes 并让它返回 bool 但我通常以这种方式编写它们以使其更灵活。

于 2014-11-06T18:11:38.150 回答