Beispiel #1
0
        /// <inheritdoc/>
        public IQueryable CreateQuery(SystemLinq.Expression expression)
        {
            var elementType = TypeHelper.GetElementType(expression.CheckNotNull(nameof(expression)).Type)
                              ?? throw new RemoteLinqException($"Failed to get element type of {expression.Type}");

            return(new RemoteQueryable(elementType, this, expression));
        }
            public RemoteLinq.Expression ToRemoteExpression(SystemLinq.Expression expression)
            {
                var partialEvalExpression = expression.CheckNotNull(nameof(expression)).PartialEval(_canBeEvaluatedLocally);
                var constExpression       = Visit(partialEvalExpression);

                return(constExpression.Unwrap());
            }
Beispiel #3
0
        /// <summary>
        /// Executes the <see cref="SystemLinq.Expression"/> and returns the raw result.
        /// </summary>
        /// <remarks>
        /// <see cref="InvalidOperationException"/> get handled for failing
        /// <see cref="Queryable.Single{TSource}(IQueryable{TSource})"/> and
        /// <see cref="Queryable.Single{TSource}(IQueryable{TSource}, SystemLinq.Expression{Func{TSource, bool}})"/>,
        /// <see cref="Queryable.First{TSource}(IQueryable{TSource})"/>,
        /// <see cref="Queryable.First{TSource}(IQueryable{TSource}, SystemLinq.Expression{Func{TSource, bool}})"/>,
        /// <see cref="Queryable.Last{TSource}(IQueryable{TSource})"/>,
        /// <see cref="Queryable.Last{TSource}(IQueryable{TSource}, SystemLinq.Expression{Func{TSource, bool}})"/>.
        /// Instead of throwing an exception, an array with the length of zero respectively two elements is returned.
        /// </remarks>
        /// <param name="expression">The <see cref="SystemLinq.Expression"/> to be executed.</param>
        /// <returns>Execution result of the <see cref="SystemLinq.Expression"/> specified.</returns>
        protected virtual object?Execute(SystemLinq.Expression expression)
        {
            expression.CheckNotNull(nameof(expression));
            try
            {
                return(ExecuteCore(expression));
            }
            catch (InvalidOperationException ex)
            {
                if (string.Equals(ex.Message, "Sequence contains no elements", StringComparison.Ordinal))
                {
                    return(Array.CreateInstance(expression.Type, 0));
                }

                if (string.Equals(ex.Message, "Sequence contains no matching element", StringComparison.Ordinal))
                {
                    return(Array.CreateInstance(expression.Type, 0));
                }

                if (string.Equals(ex.Message, "Sequence contains more than one element", StringComparison.Ordinal))
                {
                    return(Array.CreateInstance(expression.Type, 2));
                }

                if (string.Equals(ex.Message, "Sequence contains more than one matching element", StringComparison.Ordinal))
                {
                    return(Array.CreateInstance(expression.Type, 2));
                }

                throw;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Executes the <see cref="SystemLinq.Expression"/> and returns the raw result.
        /// </summary>
        /// <param name="expression">The <see cref="SystemLinq.Expression"/> to be executed.</param>
        /// <param name="cancellation">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
        /// <returns>Execution result of the <see cref="SystemLinq.Expression"/> specified.</returns>
        protected override async ValueTask <object?> ExecuteCoreAsync(SystemLinq.Expression expression, CancellationToken cancellation)
        {
            cancellation.ThrowIfCancellationRequested();

            var queryResult = expression.CheckNotNull(nameof(expression)).CompileAndInvokeExpression();

            if (queryResult is not null && queryResult.GetType().Implements(typeof(ValueTask <>), out var genericArguments))
            {
                var m = typeof(ValueTask <>).MakeGenericType(genericArguments !).GetMethodEx(nameof(ValueTask <int> .AsTask));
                queryResult = m.Invoke(queryResult, null);
            }

            if (queryResult is Task task)
            {
                if (!expression.Type.Implements(typeof(Task <>), out var resultType))
                {
                    resultType = task
                                 .GetType()
                                 .GetGenericArguments()
                                 .ToArray();
                }

                if (resultType.Length != 1)
                {
                    throw new RemoteLinqException($"Failed to retrieve the result type for async query result {task.GetType()}");
                }

                try
                {
                    queryResult = await GetTaskResultAsync(task, resultType[0]).ConfigureAwait(false);
                }
                catch (InvalidOperationException ex)
                {
                    // workarround for issue https://github.com/dotnet/efcore/issues/18742 (relevant for ef core prior version 5.0)
                    if (string.Equals(ex.Message, "Enumerator failed to MoveNextAsync.", StringComparison.Ordinal))
                    {
                        throw new InvalidOperationException("Sequence contains no elements", ex);
                    }

                    throw;
                }
            }

            if (queryResult is null)
            {
                return(null);
            }

            cancellation.ThrowIfCancellationRequested();

            if (queryResult is IQueryable queryable)
            {
                // force query execution
                task        = Helper.ToListAsync(queryable, cancellation);
                queryResult = await GetTaskResultAsync(task, typeof(List <>).MakeGenericType(queryable.ElementType)).ConfigureAwait(false);
            }

            return(queryResult);
        }
        protected override IAsyncEnumerable <object?> ExecuteAsyncStream(SystemLinq.Expression expression, CancellationToken cancellation)
        {
            if (!expression.CheckNotNull(nameof(expression)).Type.Implements(typeof(IQueryable <>)))
            {
                throw new ArgumentException("Expression must be of type IQueryable<>", nameof(expression));
            }

            var queryable = (IQueryable)expression.CompileAndInvokeExpression() !;

            return(queryable.ExecuteAsAsyncStreamWithCancellation(cancellation));
        }
        /// <summary>
        /// Executes the <see cref="SystemLinq.Expression"/> and returns the raw result.
        /// </summary>
        /// <param name="expression">The <see cref="SystemLinq.Expression"/> to be executed.</param>
        /// <param name="cancellation">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
        /// <returns>Execution result of the <see cref="SystemLinq.Expression"/> specified.</returns>
        protected override async ValueTask <object?> ExecuteCoreAsync(SystemLinq.Expression expression, CancellationToken cancellation)
        {
            cancellation.ThrowIfCancellationRequested();

            var queryResult = expression.CheckNotNull(nameof(expression)).CompileAndInvokeExpression();

            if (queryResult is not null && queryResult.GetType().Implements(typeof(ValueTask <>), out var genericArguments))
            {
                var m = typeof(ValueTask <>).MakeGenericType(genericArguments).GetMethodEx(nameof(ValueTask <int> .AsTask));
                queryResult = m.Invoke(queryResult, null);
            }

            if (queryResult is Task task)
            {
                if (!expression.Type.Implements(typeof(Task <>), out var resultType))
                {
                    resultType = task
                                 .GetType()
                                 .GetGenericArguments()
                                 .ToArray();
                }

                if (resultType.Length != 1)
                {
                    throw new RemoteLinqException($"Failed to retrieve the result type for async query result {task.GetType()}");
                }

                queryResult = await GetTaskResultAsync(task, resultType[0]).ConfigureAwait(false);
            }

            if (queryResult is null)
            {
                return(null);
            }

            cancellation.ThrowIfCancellationRequested();

            if (queryResult is IQueryable queryable)
            {
                // force query execution
                task        = Helper.ToListAsync(queryable, cancellation);
                queryResult = await GetTaskResultAsync(task, typeof(List <>).MakeGenericType(queryable.ElementType)).ConfigureAwait(false);
            }

            return(queryResult);
        }
Beispiel #7
0
        /// <summary>
        /// Executes the <see cref="SystemLinq.Expression"/> and returns the raw result.
        /// </summary>
        /// <param name="expression">The <see cref="SystemLinq.Expression"/> to be executed.</param>
        /// <returns>Execution result of the <see cref="SystemLinq.Expression"/> specified.</returns>
        protected static object?ExecuteCore(SystemLinq.Expression expression)
        {
            var queryResult = expression.CheckNotNull(nameof(expression)).CompileAndInvokeExpression();

            if (queryResult is null)
            {
                return(null);
            }

            var queryableType = queryResult.GetType();

            if (queryableType.Implements(typeof(IQueryable <>), out var genericType))
            {
                // force query execution
                queryResult = MethodInfos.Enumerable.ToArray.MakeGenericMethod(genericType[0]).InvokeAndUnwrap(null, queryResult);
            }

            return(queryResult);
        }
 /// <summary>
 /// 检查测试信息信息是否存在
 /// </summary>
 /// <param name="predicate">检查谓语表达式</param>
 /// <param name="id">更新的测试信息编号</param>
 /// <returns>测试信息是否存在</returns>
 public bool CheckTestInfoExists(Expression<Func<TestInfo, bool>> predicate, int id = 0)
 {
     predicate.CheckNotNull("predicate");
     return TestInfoRepository.CheckExists(predicate, id);
 }
Beispiel #9
0
 /// <summary>
 /// 以 Expression.OrElse 组合两个Expression表达式
 /// </summary>
 /// <typeparam name="T">表达式的主实体类型</typeparam>
 /// <param name="first">第一个Expression表达式</param>
 /// <param name="second">要组合的Expression表达式</param>
 /// <returns>组合后的表达式</returns>
 public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > first, Expression <Func <T, bool> > second)
 {
     first.CheckNotNull("first");
     second.CheckNotNull("second");
     return(first.Compose(second, Expression.OrElse));
 }