Esempio n. 1
0
    public static void ApplyGlobalFilters <TInterface>(this ModelBuilder modelBuilder, Expression <Func <TInterface, bool> > expression)
    {
        var entities = modelBuilder.Model
                       .GetEntityTypes()
                       .Where(e => e.ClrType.GetInterface(typeof(TInterface).Name) != null)
                       .Select(e => e.ClrType);

        foreach (var entity in entities)
        {
            var newParam = Expression.Parameter(entity);
            var newbody  = ReplacingExpressionVisitor.Replace(expression.Parameters.Single(), newParam, expression.Body);
            modelBuilder.Entity(entity).HasQueryFilter(Expression.Lambda(newbody, newParam));
        }
    }
    /// <summary>
    /// Apply global filters to all types inherited from T.
    /// </summary>
    /// <typeparam name="T">Base type for entries.</typeparam>
    /// <param name="modelBuilder">Model builder.</param>
    /// <param name="expression">Expression to filter.</param>
    public static void ApplyGlobalFilters <T>(this ModelBuilder modelBuilder, Expression <Func <T, bool> > expression)
    {
        IEnumerable <Type>?entities = modelBuilder.Model
                                      .GetEntityTypes()
                                      .Where(e => typeof(T).IsAssignableFrom(e.ClrType))
                                      .Select(e => e.ClrType);

        foreach (Type?entity in entities)
        {
            ParameterExpression?newParam = Expression.Parameter(entity);
            Expression?         newbody  = ReplacingExpressionVisitor.Replace(expression.Parameters.Single(), newParam, expression.Body);
            modelBuilder.Entity(entity).HasQueryFilter(Expression.Lambda(newbody, newParam));
        }
    }
        protected override ShapedQueryExpression TranslateSum(ShapedQueryExpression source, LambdaExpression selector, Type resultType)
        {
            var selectExpression = (SelectExpression)source.QueryExpression;

            selectExpression.PrepareForAggregate();
            var newSelector = selector == null ||
                              selector.Body == selector.Parameters[0]
                ? selectExpression.GetMappedProjection(new ProjectionMember())
                : ReplacingExpressionVisitor.Replace(selector.Parameters.Single(), source.ShaperExpression, selector.Body);

            var projection = _sqlTranslator.TranslateSum(newSelector);

            return(AggregateResultShaper(source, projection, throwOnNullResult: false, resultType));
        }
        protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
        {
            if (selector.Body == selector.Parameters[0])
            {
                return(source);
            }

            var newSelectorBody = ReplacingExpressionVisitor.Replace(selector.Parameters.Single(), source.ShaperExpression, selector.Body);

            source.ShaperExpression = _projectionBindingExpressionVisitor
                                      .Translate((SelectExpression)source.QueryExpression, newSelectorBody);

            return(source);
        }
Esempio n. 5
0
 public static void ApplyGlobalFilters <TInterface>(this ModelBuilder modelBuilder,
                                                    Expression <Func <TInterface, bool> > expression)
 {
     foreach (var entityType in modelBuilder.Model.GetEntityTypes())
     {
         if (entityType.ClrType.GetInterface(typeof(TInterface).Name) != null)
         {
             var newParams = Expression.Parameter(entityType.ClrType);
             var newBody   = ReplacingExpressionVisitor.Replace(
                 expression.Parameters.Single(), newParams, expression.Body);
             modelBuilder.Entity(entityType.ClrType).HasQueryFilter(Expression.Lambda(newBody, newParams));
         }
     }
 }
Esempio n. 6
0
            protected Expression ExpandNavigation(
                Expression root, EntityReference entityReference, INavigation navigation, bool derivedTypeConversion)
            {
                if (entityReference.NavigationMap.TryGetValue(navigation, out var expansion))
                {
                    return(expansion);
                }

                if (navigation.ForeignKey.IsOwnership)
                {
                    var ownedEntityReference = new EntityReference(navigation.GetTargetType());
                    ownedEntityReference.MarkAsOptional();
                    ownedEntityReference.SetIncludePaths(entityReference.IncludePaths[navigation]);

                    var ownedExpansion = new OwnedNavigationReference(root, navigation, ownedEntityReference);
                    entityReference.NavigationMap[navigation] = ownedExpansion;
                    return(ownedExpansion);
                }

                var innerQueryableType = navigation.GetTargetType().ClrType;
                var innerQueryable     = NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(innerQueryableType);
                var innerSource        = (NavigationExpansionExpression)_navigationExpandingExpressionVisitor.Visit(innerQueryable);

                if (entityReference.IncludePaths.ContainsKey(navigation))
                {
                    var innerIncludeTreeNode = entityReference.IncludePaths[navigation];
                    var innerEntityReference = (EntityReference)((NavigationTreeExpression)innerSource.PendingSelector).Value;
                    innerEntityReference.SetIncludePaths(innerIncludeTreeNode);
                }

                var        innerParameter = Expression.Parameter(innerSource.SourceElementType, "i");
                Expression outerKey;

                if (root is NavigationExpansionExpression innerNavigationExpansionExpression &&
                    innerNavigationExpansionExpression.CardinalityReducingGenericMethodInfo != null)
                {
                    // This is FirstOrDefault ending so we need to push down properties.
                    var temporaryParameter = Expression.Parameter(root.Type);
                    var temporaryKey       = CreateKeyAccessExpression(temporaryParameter,
                                                                       navigation.IsDependentToPrincipal()
                            ? navigation.ForeignKey.Properties
                            : navigation.ForeignKey.PrincipalKey.Properties);
                    var newSelector = ReplacingExpressionVisitor.Replace(
                        temporaryParameter,
                        innerNavigationExpansionExpression.PendingSelector,
                        temporaryKey);
                    innerNavigationExpansionExpression.ApplySelector(newSelector);
                    outerKey = innerNavigationExpansionExpression;
                }
        // This is an expansion on the limitation in EFCore as described in ConvertFilterExpression<T>.
        // Since EFCore currently only allows 1 HasQueryFilter() call (and ignores all previous calls),
        // we need to create a single lambda expression for all filters.
        // See: https://github.com/aspnet/EntityFrameworkCore/issues/10275
        /// <summary>
        /// Combines the query filters.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="andAlsoExpressions">The and also expressions.</param>
        /// <returns>LambdaExpression.</returns>
        private static LambdaExpression CombineQueryFilters(Type entityType, IEnumerable <LambdaExpression> andAlsoExpressions)
        {
            var newParam = Expression.Parameter(entityType);

            var andAlsoExprBase = (Expression <Func <BaseTenantEntity, bool> >)(_ => true);
            var andAlsoExpr     = ReplacingExpressionVisitor.Replace(andAlsoExprBase.Parameters.Single(), newParam, andAlsoExprBase.Body);

            foreach (var expressionBase in andAlsoExpressions.EnsureNotNull())
            {
                var expression = ReplacingExpressionVisitor.Replace(expressionBase.Parameters.Single(), newParam, expressionBase.Body);
                andAlsoExpr = Expression.AndAlso(andAlsoExpr, expression);
            }

            return(Expression.Lambda(andAlsoExpr, newParam));
        }
Esempio n. 8
0
        public static LinqBatchItem <TResult> Create <T, TResult>(IQueryable <T> query, Expression <Func <IQueryable <T>, TResult> > selector)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }
            var expression = ReplacingExpressionVisitor
                             .Replace(selector.Parameters.Single(), query.Expression, selector.Body);

            return(GetForQuery <TResult>(query, expression));
        }
Esempio n. 9
0
        /// <summary>
        ///     Takes <see cref="EqualsExpression" /> and replaces the two parameters with the given expressions,
        ///     returning the transformed body.
        /// </summary>
        /// <param name="leftExpression"> The new left expression. </param>
        /// <param name="rightExpression"> The new right expression. </param>
        /// <returns> The body of the lambda with left and right parameters replaced.</returns>
        public virtual Expression ExtractEqualsBody(
            [NotNull] Expression leftExpression,
            [NotNull] Expression rightExpression)
        {
            Check.NotNull(leftExpression, nameof(leftExpression));
            Check.NotNull(rightExpression, nameof(rightExpression));

            return(ReplacingExpressionVisitor.Replace(
                       EqualsExpression.Parameters[1],
                       rightExpression,
                       ReplacingExpressionVisitor.Replace(
                           EqualsExpression.Parameters[0],
                           leftExpression,
                           EqualsExpression.Body)));
        }
        protected override Expression VisitConstant(ConstantExpression constantExpression)
        {
            if (_store != null && constantExpression.IsEntityQueryable())
            {
                var type       = ((IQueryable)constantExpression.Value).ElementType;
                var entityType = _queryCompilationContext.Model.FindEntityType(type)?.RootType();

                if (entityType != null && _store.Dictionary.TryGetValue(type, out var lambda))
                {
                    Expression newExpression = constantExpression;

                    var parameterizedFilter
                        = (LambdaExpression)_queryModelGenerator
                          .ExtractParameters(
                              _queryCompilationContext.Logger,
                              lambda,
                              new Parameters(this.ContextParameters),
                              parameterize: false,
                              generateContextAccessors: true);

                    var oldParameterExpression = parameterizedFilter.Parameters[0];
                    var newParameterExpression = Expression.Parameter(type, oldParameterExpression.Name);

                    var predicateExpression
                        = ReplacingExpressionVisitor
                          .Replace(
                              oldParameterExpression,
                              newParameterExpression,
                              parameterizedFilter.Body);

                    var whereExpression
                        = Expression.Call(
                              _whereMethod.MakeGenericMethod(type),
                              newExpression,
                              Expression.Lambda(
                                  predicateExpression,
                                  newParameterExpression));

                    var subQueryModel = _queryModelGenerator.ParseQuery(whereExpression);

                    newExpression = new SubQueryExpression(subQueryModel);

                    return(newExpression);
                }
            }

            return(base.VisitConstant(constantExpression));
        }
Esempio n. 11
0
        /// <summary>
        /// Wraps the query in a deferred <see cref="IFutureValue{T}"/> which will trigger a batch of all pending future queries
        /// when its <see cref="IFutureValue{T}.Value"/> is read.
        /// </summary>
        /// <param name="source">An <see cref="T:System.Linq.IQueryable`1" /> to convert to a future query.</param>
        /// <param name="selector">An aggregation function to apply to <paramref name="source"/>.</param>
        /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
        /// <typeparam name="TResult">The type of the value returned by the function represented by <paramref name="selector"/>.</typeparam>
        /// <returns>A <see cref="IFutureValue{T}"/>.</returns>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
        /// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
        public static IFutureValue <TResult> ToFutureValue <TSource, TResult>(this IQueryable <TSource> source, Expression <Func <IQueryable <TSource>, TResult> > selector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (!(source.Provider is INhQueryProvider provider))
            {
                throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
            }

            var expression = ReplacingExpressionVisitor
                             .Replace(selector.Parameters.Single(), source.Expression, selector.Body);

            return(provider.ExecuteFutureValue <TResult>(expression));
        }
        /// <summary>
        /// Agrega un filtro global.
        /// </summary>
        /// <typeparam name="TInterface">Tipo de interface.</typeparam>
        /// <param name="modelBuilder">Modelo de entidades.</param>
        /// <param name="expression">Expresión a validar.</param>
        public static void WithFilter <TInterface>(this ModelBuilder modelBuilder, Expression <Func <TInterface, bool> > expression)
        {
            var entities = modelBuilder.GetEntityTypes <TInterface>();

            if (entities is not null)
            {
                foreach (var entity in entities)
                {
                    var newParam = Expression.Parameter(entity);

                    var newbody = ReplacingExpressionVisitor.Replace(expression?.Parameters.Single(), newParam, expression?.Body);

                    modelBuilder?.Entity(entity).HasQueryFilter(Expression.Lambda(newbody, newParam));
                }
            }
        }
        /// <summary>
        ///     Replaces the given parameter with a back-reference to the <see cref="IQuerySource" /> corresponding to
        ///     <paramref name="referencedNode" />.
        /// </summary>
        /// <param name="referencedNode">The referenced node.</param>
        /// <param name="parameterToReplace">The parameter to replace with a <see cref="QuerySourceReferenceExpression" />.</param>
        /// <param name="expression">The expression in which to replace the parameter.</param>
        /// <param name="context">The clause generation context.</param>
        /// <returns>
        ///     <paramref name="expression" />, with <paramref name="parameterToReplace" /> replaced with a
        ///     <see cref="QuerySourceReferenceExpression" />
        ///     pointing to the clause corresponding to <paramref name="referencedNode" />.
        /// </returns>
        public static Expression ReplaceParameterWithReference(
            IQuerySourceExpressionNode referencedNode,
            ParameterExpression parameterToReplace,
            Expression expression,
            ClauseGenerationContext context)
        {
            ArgumentUtility.CheckNotNull("referencedNode", referencedNode);
            ArgumentUtility.CheckNotNull("parameterToReplace", parameterToReplace);
            ArgumentUtility.CheckNotNull("expression", expression);
            ArgumentUtility.CheckNotNull("context", context);

            var clause = GetQuerySourceForNode(referencedNode, context);
            var referenceExpression = new QuerySourceReferenceExpression(clause);

            return(ReplacingExpressionVisitor.Replace(parameterToReplace, referenceExpression, expression));
        }
        public void SetUp()
        {
            _querySource      = ExpressionHelper.CreateMainFromClause_Int();
            _sourceExpression = new QuerySourceReferenceExpression(_querySource);

            var originalFunc = ExpressionHelper.CreateLambdaExpression <int, int, int> ((total, i) => total + i);

            _func = Expression.Lambda(
                ReplacingExpressionVisitor.Replace(originalFunc.Parameters[1], _sourceExpression, originalFunc.Body),
                originalFunc.Parameters[0]);
            _resultSelector = ExpressionHelper.CreateLambdaExpression <int, string> (total => total.ToString());

            _seed = Expression.Constant(12);
            _resultOperatorWithoutResultSelector = new AggregateFromSeedResultOperator(_seed, _func, null);
            _resultOperatorWithResultSelector    = new AggregateFromSeedResultOperator(_seed, _func, _resultSelector);
        }
        private static Expression CreateSnapshotValueExpression(Expression expression, IPropertyBase propertyBase)
        {
            if (propertyBase is IProperty property)
            {
                var comparer = property.GetValueComparer() ?? property.FindMapping()?.Comparer;

                if (comparer != null)
                {
                    expression = ReplacingExpressionVisitor.Replace(
                        comparer.SnapshotExpression.Parameters.Single(),
                        expression,
                        comparer.SnapshotExpression.Body);
                }
            }

            return(expression);
        }
        public override Expression Resolve(
            ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
        {
            LinqUtility.CheckNotNull("inputParameter", inputParameter);
            LinqUtility.CheckNotNull("expressionToBeResolved", expressionToBeResolved);

            if (IsLetNode)
            {
                // We modify the structure of the stream of data coming into this node by our selector,
                // so we first resolve the selector (adapted to include a reference to the let clause), then we substitute the result for the inputParameter
                // in the expressionToBeResolved.
                var resolvedSelector = GetResolvedAdaptedSelector(clauseGenerationContext);
                return(ReplacingExpressionVisitor.Replace(inputParameter, resolvedSelector, expressionToBeResolved));
            }

            return(base.Resolve(inputParameter, expressionToBeResolved, clauseGenerationContext));
        }
        public virtual Expression Inject(Expression expression)
        {
            var result = Visit(expression);

            if (_expressions.All(e => e.NodeType == ExpressionType.Assign))
            {
                result = new ReplacingExpressionVisitor(_expressions.Cast <BinaryExpression>()
                                                        .ToDictionary(e => e.Left, e => e.Right)).Visit(result);
            }
            else
            {
                _expressions.Add(result);
                result = Expression.Block(_variables, _expressions);
            }

            return(ConvertToLambda(result, Expression.Parameter(result.Type, "result")));
        }
Esempio n. 18
0
        public override Expression CustomizeDataReaderExpression(Expression expression)
        {
            if (SpatialConverter is null)
            {
                return(expression);
            }

            if (expression.Type != SpatialConverter.ProviderClrType)
            {
                expression = Expression.Convert(expression, SpatialConverter.ProviderClrType);
            }

            return(ReplacingExpressionVisitor.Replace(
                       SpatialConverter.ConvertFromProviderExpression.Parameters.Single(),
                       expression,
                       SpatialConverter.ConvertFromProviderExpression.Body));
        }
        internal static void AddQueryFilter <T>(this EntityTypeBuilder entityTypeBuilder, Expression <Func <T, bool> > expression)
        {
            var parameterType    = Expression.Parameter(entityTypeBuilder.Metadata.ClrType);
            var expressionFilter = ReplacingExpressionVisitor.Replace(expression.Parameters.Single(), parameterType, expression.Body);

            var currentQueryFilter = entityTypeBuilder.Metadata.GetQueryFilter();

            if (currentQueryFilter != null)
            {
                var currentExpressionFilter = ReplacingExpressionVisitor.Replace(currentQueryFilter.Parameters.Single(), parameterType, currentQueryFilter.Body);
                expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter);
            }

            var lambdaExpression = Expression.Lambda(expressionFilter, parameterType);

            entityTypeBuilder.HasQueryFilter(lambdaExpression);
        }
        protected override ShapedQueryExpression TranslateGroupBy(ShapedQueryExpression source, LambdaExpression keySelector, LambdaExpression elementSelector, LambdaExpression resultSelector)
        {
            var remappedKeySelector = RemapLambdaBody(source, keySelector);

            var translatedKey = TranslateGroupingKey(remappedKeySelector);

            if (translatedKey != null)
            {
                if (elementSelector != null)
                {
                    source = TranslateSelect(source, elementSelector);
                }

                var inMemoryQueryExpression = (InMemoryQueryExpression)source.QueryExpression;
                source.ShaperExpression = inMemoryQueryExpression.ApplyGrouping(translatedKey, source.ShaperExpression);

                if (resultSelector == null)
                {
                    return(source);
                }

                var keyAccessExpression = Expression.MakeMemberAccess(
                    source.ShaperExpression,
                    source.ShaperExpression.Type.GetTypeInfo().GetMember(nameof(IGrouping <int, int> .Key))[0]);

                var original1 = resultSelector.Parameters[0];
                var original2 = resultSelector.Parameters[1];

                var newResultSelectorBody = new ReplacingExpressionVisitor(
                    new Dictionary <Expression, Expression> {
                    { original1, keyAccessExpression },
                    { original2, source.ShaperExpression }
                }).Visit(resultSelector.Body);

                newResultSelectorBody = ExpandWeakEntities(inMemoryQueryExpression, newResultSelectorBody);

                source.ShaperExpression = _projectionBindingExpressionVisitor.Translate(inMemoryQueryExpression, newResultSelectorBody);

                inMemoryQueryExpression.PushdownIntoSubquery();

                return(source);
            }

            return(null);
        }
Esempio n. 21
0
        private LambdaExpression CombineQueryFilters(Type entityType, LambdaExpression baseFilter, IEnumerable <LambdaExpression> andAlsoExpressions)
        {
            var newParam = Expression.Parameter(entityType);

            var andAlsoExprBase = (Expression <Func <IEntity, bool> >)(_ => true);
            var andAlsoExpr     = ReplacingExpressionVisitor.Replace(andAlsoExprBase.Parameters.Single(), newParam, andAlsoExprBase.Body);

            foreach (var expressionBase in andAlsoExpressions)
            {
                var expression = ReplacingExpressionVisitor.Replace(expressionBase.Parameters.Single(), newParam, expressionBase.Body);
                andAlsoExpr = Expression.AndAlso(andAlsoExpr, expression);
            }

            var baseExp = ReplacingExpressionVisitor.Replace(baseFilter.Parameters.Single(), newParam, baseFilter.Body);
            var exp     = Expression.OrElse(baseExp, andAlsoExpr);

            return(Expression.Lambda(exp, newParam));
        }
Esempio n. 22
0
        internal static void AddQueryFilter(this EntityTypeBuilder entityTypeBuilder, LambdaExpression expression)
        {
            var parameterType    = Expression.Parameter(entityTypeBuilder.Metadata.ClrType);
            var expressionFilter = ReplacingExpressionVisitor.Replace(expression.Parameters.Single(), parameterType, expression.Body);

            //var internalEntityTypeBuilder = entityTypeBuilder.GetInternalEntityTypeBuilder();
            //if (internalEntityTypeBuilder.Metadata.QueryFilter != null)
            //{
            //    var currentQueryFilter = internalEntityTypeBuilder.Metadata.QueryFilter;
            //    var currentExpressionFilter = ReplacingExpressionVisitor.Replace(
            //        currentQueryFilter.Parameters.Single(), parameterType, currentQueryFilter.Body);
            //    expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter);
            //}

            var lambdaExpression = Expression.Lambda(expressionFilter, parameterType);

            entityTypeBuilder.HasQueryFilter(lambdaExpression);
        }
        private Expression GetSelector(MethodCallExpression methodCallExpression, GroupByShaperExpression groupByShaperExpression)
        {
            if (methodCallExpression.Arguments.Count == 1)
            {
                return(groupByShaperExpression.ElementSelector);
            }

            if (methodCallExpression.Arguments.Count == 2)
            {
                var selectorLambda = methodCallExpression.Arguments[1].UnwrapLambdaFromQuote();
                return(ReplacingExpressionVisitor.Replace(
                           selectorLambda.Parameters[0],
                           groupByShaperExpression.ElementSelector,
                           selectorLambda.Body));
            }

            throw new InvalidOperationException();
        }
Esempio n. 24
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override Expression VisitConstant(ConstantExpression constantExpression)
        {
            if (constantExpression.IsEntityQueryable())
            {
                var type       = ((IQueryable)constantExpression.Value).ElementType;
                var entityType = _queryCompilationContext.Model.FindEntityType(type)?.RootType();

                if (entityType?.QueryFilter != null)
                {
                    var parameterizedFilter
                        = (LambdaExpression)_queryModelGenerator
                          .ExtractParameters(
                              _queryCompilationContext.Logger,
                              entityType.QueryFilter,
                              _parameters,
                              parameterize: false,
                              generateContextAccessors: true);

                    var oldParameterExpression = parameterizedFilter.Parameters[0];
                    var newParameterExpression = Expression.Parameter(type, oldParameterExpression.Name);

                    var predicateExpression
                        = ReplacingExpressionVisitor
                          .Replace(
                              oldParameterExpression,
                              newParameterExpression,
                              parameterizedFilter.Body);

                    var whereExpression
                        = Expression.Call(
                              _whereMethod.MakeGenericMethod(type),
                              constantExpression,
                              Expression.Lambda(
                                  predicateExpression,
                                  newParameterExpression));

                    var subQueryModel = _queryModelGenerator.ParseQuery(whereExpression);

                    return(new SubQueryExpression(subQueryModel));
                }
            }

            return(constantExpression);
        }
        protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
        {
            var test = Visit(conditionalExpression.Test);

            if (test is BinaryExpression binaryTest &&
                (binaryTest.NodeType == ExpressionType.Equal ||
                 binaryTest.NodeType == ExpressionType.NotEqual))
            {
                var isLeftNullConstant  = IsNullConstant(binaryTest.Left);
                var isRightNullConstant = IsNullConstant(binaryTest.Right);

                if ((isLeftNullConstant == isRightNullConstant) ||
                    (binaryTest.NodeType == ExpressionType.Equal &&
                     !IsNullConstant(conditionalExpression.IfTrue)) ||
                    (binaryTest.NodeType == ExpressionType.NotEqual &&
                     !IsNullConstant(conditionalExpression.IfFalse)))
                {
                    return(conditionalExpression);
                }

                var caller          = isLeftNullConstant ? binaryTest.Right : binaryTest.Left;
                var accessOperation = binaryTest.NodeType == ExpressionType.Equal
                    ? conditionalExpression.IfFalse
                    : conditionalExpression.IfTrue;

                // Unwrap nested nullConditional
                if (caller is NullConditionalExpression nullConditionalCaller)
                {
                    accessOperation = ReplacingExpressionVisitor.Replace(
                        _nullConditionalRemovingExpressionVisitor.Visit(nullConditionalCaller.AccessOperation),
                        nullConditionalCaller,
                        accessOperation);
                }

                if (_nullSafeAccessVerifyingExpressionVisitor.Verify(caller, accessOperation))
                {
                    return(new NullConditionalExpression(caller, accessOperation));
                }
            }

            return(base.VisitConditional(conditionalExpression));
        }
        /// <summary>
        ///     Reduces the node and then calls the visitor delegate on the reduced expression.
        ///     The method throws an exception if the node is not
        ///     reducible.
        /// </summary>
        /// <returns>
        ///     The expression being visited, or an expression which should replace it in the tree.
        /// </returns>
        /// <param name="visitor">An instance of <see cref="T:System.Func`2" />.</param>
        protected override Expression VisitChildren(ExpressionVisitor visitor)
        {
            var newNullableCaller = visitor.Visit(NullableCaller);
            var newCaller         = visitor.Visit(Caller);

            var newAccessOperation
                = visitor.Visit(
                      ReplacingExpressionVisitor
                      .Replace(Caller, newCaller, AccessOperation));

            if (newNullableCaller != NullableCaller ||
                newCaller != Caller ||
                newAccessOperation != AccessOperation)
            {
                return(new NullConditionalExpression(
                           newNullableCaller, newCaller, newAccessOperation));
            }

            return(this);
        }
Esempio n. 27
0
            private static Expression CreateGetStoreValueExpression(
                Expression jObjectExpression,
                string storeName,
                CoreTypeMapping typeMapping,
                Type clrType)
            {
                var        jTokenExpression = Expression.Call(jObjectExpression, _getItemMethodInfo, Expression.Constant(storeName));
                Expression valueExpression;

                var converter = typeMapping.Converter;

                if (converter != null)
                {
                    valueExpression = ConvertJTokenToType(jTokenExpression, converter.ProviderClrType);

                    valueExpression = ReplacingExpressionVisitor.Replace(
                        converter.ConvertFromProviderExpression.Parameters.Single(),
                        valueExpression,
                        converter.ConvertFromProviderExpression.Body);

                    if (valueExpression.Type != clrType)
                    {
                        valueExpression = Expression.Convert(valueExpression, clrType);
                    }
                }
                else
                {
                    valueExpression = ConvertJTokenToType(jTokenExpression, clrType);
                }

                if (clrType.IsNullableType())
                {
                    valueExpression =
                        Expression.Condition(
                            Expression.Call(_isNullMethodInfo, jTokenExpression),
                            Expression.Default(valueExpression.Type),
                            valueExpression);
                }

                return(valueExpression);
            }
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
        {
            if (selector.Body == selector.Parameters[0])
            {
                return(source);
            }

            var selectExpression = (SelectExpression)source.QueryExpression;

            if (selectExpression.IsDistinct)
            {
                throw new InvalidOperationException();
            }

            var newSelectorBody = ReplacingExpressionVisitor.Replace(selector.Parameters.Single(), source.ShaperExpression, selector.Body);

            source.ShaperExpression = _projectionBindingExpressionVisitor
                                      .Translate(selectExpression, newSelectorBody);

            return(source);
        }
        public static void UseSoftDelete(this DbContext context, ModelBuilder modelBuilder)
        {
            modelBuilder.Model.GetEntityTypes()
            .Where(entityType => typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType))
            .ToList()
            .ForEach(entityType =>
            {
                modelBuilder.Entity(entityType.ClrType)
                .HasQueryFilter(ConvertFilterExpression <ISoftDelete>(x => !x.IsDeleted, entityType.ClrType));
            });

            LambdaExpression ConvertFilterExpression <TInterface>(
                Expression <Func <TInterface, bool> > filterExpression,
                Type entityType)
            {
                var newParam = Expression.Parameter(entityType, filterExpression.Parameters[0].Name);
                var newBody  = ReplacingExpressionVisitor.Replace(filterExpression.Parameters.Single(), newParam, filterExpression.Body);

                return(Expression.Lambda(newBody, newParam));
            }
        }
Esempio n. 30
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
        {
            Check.NotNull(source, nameof(source));
            Check.NotNull(selector, nameof(selector));

            if (selector.Body == selector.Parameters[0])
            {
                return(source);
            }

            var selectExpression = (SelectExpression)source.QueryExpression;

            if (selectExpression.IsDistinct)
            {
                return(null);
            }

            var newSelectorBody = ReplacingExpressionVisitor.Replace(selector.Parameters.Single(), source.ShaperExpression, selector.Body);

            return(source.UpdateShaperExpression(_projectionBindingExpressionVisitor.Translate(selectExpression, newSelectorBody)));
        }