1

クエリ可能な結合への参加を見つける方法を探しています...

基本的に、クエリ可能なステートメントの結合操作でモデル クラス X が使用されているかどうかを確認したい。David Fowl のQueryInterceptorを使用して、式ビジターを IQueryable に配置できます。次に、タイプがクラス X のパラメータの Lambda 式 (結合は一般的に表現されているように見えます) をチェックします。ビジターは、ヒットのフラグを切り替えることができます。

他の方法?繰り返しますが、クラス X が結合に関与しているかどうかだけに関心があります。

4

1 に答える 1

1

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 を返すようにすることもできますが、私は通常、より柔軟にするためにこのように記述します。

于 2014-11-06T18:11:38.150 に答える