Exemplo n.º 1
0
        public static AsyncTransformExpression <TSource, TOuter> Then <TOuter>([NotNull] AsyncTransformExpression <TSource, TResult> left, [NotNull] AsyncTransformExpression <TResult, TOuter> right)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }

            if (left.IsIdentity())
            {             // we can optimize the left expression away, since we know that TSource == TResult !
                //note: fool the compiler into believing that TSource == TResult
                return((AsyncTransformExpression <TSource, TOuter>)(object) right);
            }

            if (right.IsIdentity())
            {             // we can optimize the right expression away, since we know that TResult == TOuter !
                return((AsyncTransformExpression <TSource, TOuter>)(object) left);
            }

            if (left.m_transform != null)
            {
                var f = left.m_transform;
                if (right.m_transform != null)
                {
                    var g = right.m_transform;
                    return(new AsyncTransformExpression <TSource, TOuter>((x) => g(f(x))));
                }
                else
                {
                    var g = right.m_asyncTransform;
                    return(new AsyncTransformExpression <TSource, TOuter>((x, ct) => g(f(x), ct)));
                }
            }
            else
            {
                var f = left.m_asyncTransform;
                if (right.m_asyncTransform != null)
                {
                    var g = right.m_asyncTransform;
                    return(new AsyncTransformExpression <TSource, TOuter>(async(x, ct) => await g(await f(x, ct).ConfigureAwait(false), ct).ConfigureAwait(false)));
                }
                else
                {
                    var g = right.m_transform;
                    return(new AsyncTransformExpression <TSource, TOuter>(async(x, ct) => g(await f(x, ct).ConfigureAwait(false))));
                }
            }
        }
        public override FdbAsyncIterator <TResult> Where(Func <TResult, bool> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            }

            // note: the only possible optimization here is if TSource == TResult, then we can combine both predicates
            // remember: limit/offset are applied AFTER the filtering, so can only combine if they are null
            // also, since transform is done after filtering, we can only optimize if transform is null (not allowed!) or the identity function
            if (m_limit == null &&
                (m_offset == null || m_offset.Value == 0) &&
                typeof(TSource) == typeof(TResult) &&                 //BUGBUG: type comparison maybe should check derived classes also ?
                m_transform.IsIdentity())
            {
                var filter = new AsyncFilterExpression <TSource>((Func <TSource, bool>)(Delegate) predicate);
                if (m_filter != null)
                {
                    filter = m_filter.AndAlso(filter);
                }

                //BUGBUG: if the query already has a select, it should be evaluated BEFORE the new filter,
                // but currently FdbWhereSelectAsyncIterator<> filters before transformations !

                return(new FdbWhereSelectAsyncIterator <TSource, TResult>(
                           m_source,
                           filter,
                           m_transform,
                           m_limit,
                           m_offset
                           ));
            }

            // no easy optimization...
            return(base.Where(predicate));
        }