Generic Join Method Using LINQ

Generic Join can be implemented using LINQ . Lets see the code to implement a Generic Join which is going to accept  two Entities and return the ResultSet which is going to be the Join of the Two Entities . I have used Entity Framework to create the Entities .

 public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values)
        {
            if (inner == null) throw new ArgumentNullException("inner");
            if (outerSelector == null) throw new ArgumentNullException("outerSelector");
            if (innerSelector == null) throw new ArgumentNullException("innerSelector");
            if (resultsSelector == null) throw new ArgumentNullException("resultsSelctor");

            System.Linq.Expressions.LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerSelector, values);
            System.Linq.Expressions.LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values);

            System.Linq.Expressions.ParameterExpression[] parameters = new System.Linq.Expressions.ParameterExpression[] {
            System.Linq.Expressions.Expression.Parameter(outer.ElementType, "outer"), System.Linq.Expressions.Expression.Parameter(inner.AsQueryable().ElementType, "inner") };
            System.Linq.Expressions.LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values);

            return outer.Provider.CreateQuery(
                System.Linq.Expressions.Expression.Call(
                    typeof(IQueryable), "Join",
                    new Type[]
                    {
                        outer.ElementType,
                        inner.AsQueryable().ElementType,
                        outerSelectorLambda.Body.Type,
                       
                        resultsSelectorLambda.Body.Type
                    },
                    outer.Expression,
                    inner.AsQueryable().Expression,
                    System.Linq.Expressions.Expression.Quote(outerSelectorLambda),
                    System.Linq.Expressions.Expression.Quote(innerSelectorLambda),
                    System.Linq.Expressions.Expression.Quote(resultsSelectorLambda)));
        }


        //The generic overload.
        public static IQueryable<T> Join<T>(this IQueryable<T> outer, IEnumerable<T> inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values)
        {
            return (IQueryable<T>)Join((IQueryable)outer, (IEnumerable)inner, outerSelector, innerSelector, resultsSelector, values);
        }