Если участвует в 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, но я обычно пишу их таким образом, чтобы сделать его более гибким.