如果参与可查询的c#加入

如果参与可查询的c#加入,c#,linq,iqueryable,expressionvisitor,C#,Linq,Iqueryable,Expressionvisitor,正在寻找参与可查询联接的方法 基本上,我想检查模型类X是否用于Queryable语句中的连接操作。使用David Foll的,我可以在IQueryable上放置一个表达式visitor。然后检查Lambda表达式(看起来连接通常是用它们表示的)是否有类X类型的参数。访问者可以为点击切换标志 其他方式?同样,我只对联接中是否涉及类X感兴趣。您可以使用ExpressionVisitor类检查表达式树并提取联接的泛型类型 在静态构造函数中,我们将使用反射来查找可查询类上连接的方法infos。在方法调用

正在寻找参与可查询联接的方法

基本上,我想检查模型类X是否用于Queryable语句中的连接操作。使用David Foll的,我可以在IQueryable上放置一个表达式visitor。然后检查Lambda表达式(看起来连接通常是用它们表示的)是否有类X类型的参数。访问者可以为点击切换标志


其他方式?同样,我只对联接中是否涉及类X感兴趣。

您可以使用ExpressionVisitor类检查表达式树并提取联接的泛型类型

在静态构造函数中,我们将使用反射来查找可查询类上连接的方法infos。在方法调用上,我们将查看调用方法是否是泛型的,以及它是否匹配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);
    }
}

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

实现这一点的唯一方法是遍历表达式树以查找该类型的用法。当然,如何进行的细节可能会有所不同,但这就是您要做的。感谢@CharlesNRice,就像查看MethodCallExpression时检查方法名称一样。完美的
IQueryable queryable ;  // your IQueryable 
var types = JoinVisitor.GetJoinTypes(queryable.Expression);