寻找参与可查询联接的方法......
基本上,我想检查模型类X是否用于Queryable语句中的连接操作。使用David Fowl的QueryInterceptor我可以将表达式访问者放在IQueryable上。然后检查Lambda表达式(看起来通常用它们表示连接)用于类型为X的参数。访问者可以为命中切换标记。
其他方式?同样,我只对X类是否参与连接感兴趣。
答案 0 :(得分: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);
然后使用can只需使用contains方法来查看类型是否在连接中。您也可以将其更改为传入GetJoinTypes类型并让它返回bool但我通常以这种方式编写它们以使其更灵活。