Esempio n. 1
0
        private static async Task <IQueryable> InvokeOperation(
            object instanceImplementMethod, MethodInfo method, object[] parameters, IEdmModel model)
        {
            object result     = method.Invoke(instanceImplementMethod, parameters);
            var    returnType = method.ReturnType;

            if (returnType == typeof(void))
            {
                return(null);
            }

            var task = result as Task;

            if (task != null)
            {
                await task;
                if (returnType.GenericTypeArguments.Any())
                {
                    returnType = returnType.GenericTypeArguments.First();
                    var resultProperty = typeof(Task <>).MakeGenericType(returnType).GetProperty("Result");
                    result = resultProperty.GetValue(task);
                }
                else
                {
                    return(null);
                }
            }

            IEdmTypeReference edmReturnType = returnType.GetReturnTypeReference(model);

            if (edmReturnType.IsCollection())
            {
                var elementClrType = returnType.GetElementType() ??
                                     returnType.GenericTypeArguments[0];
                if (result == null)
                {
                    return(ExpressionHelpers.CreateEmptyQueryable(elementClrType));
                }

                var enumerableType = result.GetType().FindGenericType(typeof(IEnumerable <>));
                if (enumerableType != null)
                {
                    return(((IEnumerable)result).AsQueryable());
                }

                // Should never hint this path, add here to make sure collection result will not hint single result part
                return(ExpressionHelpers.CreateEmptyQueryable(elementClrType));
            }

            // This means this is single result
            // cannot return new[] { result }.AsQueryable(); as need to return in its own type but not object type
            var objectQueryable = new[] { result }.AsQueryable();
            var castMethodInfo = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(returnType);
            var castedResult   = castMethodInfo.Invoke(null, new object[] { objectQueryable });
            var typedQueryable = ExpressionHelperMethods.QueryableAsQueryable
                                 .Invoke(null, new object[] { castedResult }) as IQueryable;

            return(typedQueryable);
        }