protected override Expression VisitMethodCall(MethodCallExpression node)
 {
     if (node.Method.Name == nameof(Enumerable.Where))
     {
         var        predicate   = node.Arguments[1] is UnaryExpression quote ? (LambdaExpression)quote.Operand : (LambdaExpression)node.Arguments[1];
         var        joinVisitor = new JoinVisitor(_edmModel, node.Arguments[0], predicate.Parameters[0]);
         Expression expression  = joinVisitor.Visit(node.Arguments[1]);
         if (node.Arguments[1] != expression)
         {
             Expression[] arguments = node.Arguments.ToArray();
             arguments[1] = expression;
             return(node.Update(node.Object !, arguments));
         }
     }
     else if (node.Method.Name == nameof(Enumerable.SelectMany) && node.Arguments.Count == 2)
     {
         var        predicate   = node.Arguments[1] is UnaryExpression quote ? (LambdaExpression)quote.Operand : (LambdaExpression)node.Arguments[1];
         var        joinVisitor = new JoinVisitor(_edmModel, node.Arguments[0], predicate.Parameters[0]);
         Expression body        = joinVisitor.Visit(predicate.Body);
         if (predicate.Body != body)
         {
             Expression[] arguments = node.Arguments.ToArray();
             arguments[1] = Expression.Lambda(body, predicate.Parameters);
             return(node.Update(node.Object !, arguments));
         }
     }
     return(base.VisitMethodCall(node));
 }
    public static IEnumerable <Type> GetJoinTypes(System.Linq.Expressions.Expression expression)
    {
        var joinVisitor = new JoinVisitor();

        joinVisitor.Visit(expression);
        return(joinVisitor.Types);
    }