Если участвует в Queryable C# присоединиться

Ищете способы найти участие в запрашиваемых объединениях...

По сути, я хочу проверить, используется ли класс модели X в операциях соединения в операторах Queryable. Используя QueryInterceptor Дэвида Фаула, я могу поместить посетителя выражения в IQueryable. Затем проверьте наличие лямбда-выражений (похоже, что объединения представлены с ними в общем) для параметров с типом класса X. Посетитель может переключить флаг для попадания.

Другие способы? Опять же, меня интересует только участие класса X в соединениях.

1 ответ

Решение

Вы можете использовать класс ExpressionVisitor для проверки дерева выражений и извлечения универсальных типов объединения.

В статическом конструкторе мы будем использовать отражение, чтобы найти информацию о методе для класса Join в классе Queryable. При вызовах методов мы увидим, является ли метод вызова универсальным и соответствует ли он методу Join в Queryable Class. Если так, то мы знаем, что первые два общих аргумента - это Внешний тип и Внутренний тип. Добавьте их в хэш-набор, чтобы удалить дубликаты.

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);

Затем use может просто использовать метод contains, чтобы увидеть, входит ли тип в соединение. Вы также можете изменить это, чтобы передать тип GetJoinTypes и заставить его возвращать bool, но я обычно пишу их таким образом, чтобы сделать его более гибким.

Другие вопросы по тегам