ExpressionVisitor クラスを使用して、式ツリーを検査し、結合のジェネリック型を引き出すことができます。
静的コンストラクターでは、リフレクションを使用して、Queryable クラスの Join のメソッド情報を見つけます。メソッド呼び出しでは、call メソッドがジェネリックかどうか、およびそれが Queryable Class の Join メソッドと一致するかどうかを確認します。そうであれば、最初の 2 つのジェネリック引数が Outer Type と Inner Type であることがわかります。重複を削除するためだけにハッシュセットに追加します。
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 を返すようにすることもできますが、私は通常、より柔軟にするためにこのように記述します。