public virtual SqlExpression Translate([NotNull] Expression expression)
        {
            Check.NotNull(expression, nameof(expression));

            var result = Visit(expression);

            if (result is SqlExpression translation)
            {
                if (translation is SqlUnaryExpression sqlUnaryExpression &&
                    sqlUnaryExpression.OperatorType == ExpressionType.Convert &&
                    sqlUnaryExpression.Type == typeof(object))
                {
                    translation = sqlUnaryExpression.Operand;
                }

                translation = SqlExpressionFactory.ApplyDefaultTypeMapping(translation);

                if (translation.TypeMapping == null)
                {
                    // The return type is not-mappable hence return null
                    return(null);
                }

                _sqlTypeMappingVerifyingExpressionVisitor.Visit(translation);

                return(translation);
            }

            return(null);
        }
Пример #2
0
        public virtual SqlExpression TranslateAverage([NotNull] Expression expression)
        {
            Check.NotNull(expression, nameof(expression));

            if (!(expression is SqlExpression sqlExpression))
            {
                sqlExpression = Translate(expression);
            }

            if (sqlExpression == null)
            {
                throw new InvalidOperationException(CoreStrings.TranslationFailed(expression.Print()));
            }

            var inputType = sqlExpression.Type.UnwrapNullableType();

            if (inputType == typeof(int) ||
                inputType == typeof(long))
            {
                sqlExpression = SqlExpressionFactory.ApplyDefaultTypeMapping(
                    SqlExpressionFactory.Convert(sqlExpression, typeof(double)));
            }

            return(inputType == typeof(float)
                ? SqlExpressionFactory.Convert(
                       SqlExpressionFactory.Function(
                           "AVG", new[] { sqlExpression }, typeof(double)),
                       sqlExpression.Type,
                       sqlExpression.TypeMapping)
                : (SqlExpression)SqlExpressionFactory.Function(
                       "AVG", new[] { sqlExpression }, sqlExpression.Type, sqlExpression.TypeMapping));
        }
        public virtual SqlExpression TranslateSum([NotNull] Expression expression)
        {
            Check.NotNull(expression, nameof(expression));

            if (!(expression is SqlExpression sqlExpression))
            {
                sqlExpression = Translate(expression);
            }

            if (sqlExpression == null)
            {
                throw new InvalidOperationException(CoreStrings.TranslationFailed(expression.Print()));
            }

            var inputType = sqlExpression.Type.UnwrapNullableType();

            return(inputType == typeof(float)
                ? SqlExpressionFactory.Convert(
                       SqlExpressionFactory.Function(
                           "SUM",
                           new[] { sqlExpression },
                           nullResultAllowed: true,
                           argumentsPropagateNullability: new[] { false },
                           typeof(double)),
                       inputType,
                       sqlExpression.TypeMapping)
                : (SqlExpression)SqlExpressionFactory.Function(
                       "SUM",
                       new[] { sqlExpression },
                       nullResultAllowed: true,
                       argumentsPropagateNullability: new[] { false },
                       inputType,
                       sqlExpression.TypeMapping));
        }
        public virtual SqlExpression Translate([NotNull] Expression expression)
        {
            Check.NotNull(expression, nameof(expression));

            var result = Visit(expression);

            if (result is SqlExpression translation)
            {
                if (translation is SqlUnaryExpression sqlUnaryExpression &&
                    sqlUnaryExpression.OperatorType == ExpressionType.Convert &&
                    sqlUnaryExpression.Type == typeof(object))
                {
                    translation = sqlUnaryExpression.Operand;
                }

                translation = SqlExpressionFactory.ApplyDefaultTypeMapping(translation);

                if ((translation is SqlConstantExpression ||
                     translation is SqlParameterExpression) &&
                    translation.TypeMapping == null)
                {
                    // Non-mappable constant/parameter
                    return(null);
                }

                _sqlTypeMappingVerifyingExpressionVisitor.Visit(translation);

                return(translation);
            }

            return(null);
        }
Пример #5
0
        protected override Expression VisitTypeBinary(TypeBinaryExpression typeBinaryExpression)
        {
            Check.NotNull(typeBinaryExpression, nameof(typeBinaryExpression));

            if (typeBinaryExpression.NodeType == ExpressionType.TypeIs &&
                Visit(typeBinaryExpression.Expression) is EntityProjectionExpression entityProjectionExpression)
            {
                var entityType = entityProjectionExpression.EntityType;
                if (entityType.GetAllBaseTypesInclusive().Any(et => et.ClrType == typeBinaryExpression.TypeOperand))
                {
                    return(SqlExpressionFactory.Constant(true));
                }

                var derivedType = entityType.GetDerivedTypes().SingleOrDefault(et => et.ClrType == typeBinaryExpression.TypeOperand);
                if (derivedType != null)
                {
                    var concreteEntityTypes = derivedType.GetConcreteDerivedTypesInclusive().ToList();
                    var discriminatorColumn = entityProjectionExpression.BindProperty(entityType.GetDiscriminatorProperty());

                    return(concreteEntityTypes.Count == 1
                        ? SqlExpressionFactory.Equal(
                               discriminatorColumn,
                               SqlExpressionFactory.Constant(concreteEntityTypes[0].GetDiscriminatorValue()))
                        : (Expression)SqlExpressionFactory.In(
                               discriminatorColumn,
                               SqlExpressionFactory.Constant(concreteEntityTypes.Select(et => et.GetDiscriminatorValue()).ToList()),
                               negated: false));
                }

                return(SqlExpressionFactory.Constant(false));
            }

            return(null);
        }
            protected override Expression VisitExtension(Expression extensionExpression)
            {
                if (extensionExpression is SelectExpression selectExpression)
                {
                    var newSelectExpression = (SelectExpression)base.VisitExtension(extensionExpression);

                    return(newSelectExpression.Predicate is SqlConstantExpression newSelectPredicateConstant &&
                           !(selectExpression.Predicate is SqlConstantExpression)
                        ? newSelectExpression.Update(
                               newSelectExpression.Projection.ToList(),
                               newSelectExpression.Tables.ToList(),
                               SqlExpressionFactory.Equal(
                                   newSelectPredicateConstant,
                                   SqlExpressionFactory.Constant(true, newSelectPredicateConstant.TypeMapping)),
                               newSelectExpression.GroupBy.ToList(),
                               newSelectExpression.Having,
                               newSelectExpression.Orderings.ToList(),
                               newSelectExpression.Limit,
                               newSelectExpression.Offset,
                               newSelectExpression.IsDistinct,
                               newSelectExpression.Alias)
                        : newSelectExpression);
                }

                return(base.VisitExtension(extensionExpression));
            }
Пример #7
0
        public virtual SqlExpression TranslateLongCount([CanBeNull] Expression expression = null)
        {
            if (expression != null)
            {
                // TODO: Translate Count with predicate for GroupBy
                return(null);
            }

            return(SqlExpressionFactory.ApplyDefaultTypeMapping(
                       SqlExpressionFactory.Function("COUNT", new[] { SqlExpressionFactory.Fragment("*") }, typeof(long))));
        }
Пример #8
0
        public virtual SqlExpression TranslateMin([NotNull] Expression expression)
        {
            Check.NotNull(expression, nameof(expression));

            if (!(expression is SqlExpression sqlExpression))
            {
                sqlExpression = Translate(expression);
            }

            return(sqlExpression != null
                ? SqlExpressionFactory.Function("MIN", new[] { sqlExpression }, sqlExpression.Type, sqlExpression.TypeMapping)
                : null);
        }
        public virtual SqlExpression TranslateLongCount([CanBeNull] Expression expression = null)
        {
            if (expression != null)
            {
                // TODO: Translate Count with predicate for GroupBy
                return(null);
            }

            return(SqlExpressionFactory.ApplyDefaultTypeMapping(
                       SqlExpressionFactory.Function(
                           "COUNT",
                           new[] { SqlExpressionFactory.Fragment("*") },
                           nullResultAllowed: false,
                           argumentsPropagateNullability: new[] { false },
                           typeof(long))));
        }
        public virtual SqlExpression TranslateMin([NotNull] Expression expression)
        {
            Check.NotNull(expression, nameof(expression));

            if (!(expression is SqlExpression sqlExpression))
            {
                sqlExpression = Translate(expression);
            }

            return(sqlExpression != null
                ? SqlExpressionFactory.Function(
                       "MIN",
                       new[] { sqlExpression },
                       nullResultAllowed : true,
                       argumentsPropagateNullability : new[] { false },
                       sqlExpression.Type,
                       sqlExpression.TypeMapping)
                : null);
        }
            protected override Expression VisitExtension(Expression extensionExpression)
            {
                if (extensionExpression is SelectExpression selectExpression)
                {
                    var newSelectExpression = (SelectExpression)base.VisitExtension(extensionExpression);

                    // if predicate is optimized to true, we can simply remove it
                    var newPredicate = newSelectExpression.Predicate is SqlConstantExpression newSelectPredicateConstant &&
                                       !(selectExpression.Predicate is SqlConstantExpression)
                        ? (bool)newSelectPredicateConstant.Value
                            ? null
                            : SqlExpressionFactory.Equal(
                        newSelectPredicateConstant,
                        SqlExpressionFactory.Constant(true, newSelectPredicateConstant.TypeMapping))
                        : newSelectExpression.Predicate;

                    var newHaving = newSelectExpression.Having is SqlConstantExpression newSelectHavingConstant &&
                                    !(selectExpression.Having is SqlConstantExpression)
                        ? (bool)newSelectHavingConstant.Value
                            ? null
                            : SqlExpressionFactory.Equal(
                        newSelectHavingConstant,
                        SqlExpressionFactory.Constant(true, newSelectHavingConstant.TypeMapping))
                        : newSelectExpression.Having;

                    return(newPredicate != newSelectExpression.Predicate ||
                           newHaving != newSelectExpression.Having
                        ? newSelectExpression.Update(
                               newSelectExpression.Projection.ToList(),
                               newSelectExpression.Tables.ToList(),
                               newPredicate,
                               newSelectExpression.GroupBy.ToList(),
                               newHaving,
                               newSelectExpression.Orderings.ToList(),
                               newSelectExpression.Limit,
                               newSelectExpression.Offset,
                               newSelectExpression.IsDistinct,
                               newSelectExpression.Alias)
                        : newSelectExpression);
                }

                return(base.VisitExtension(extensionExpression));
            }
Пример #12
0
            protected override Expression VisitSqlUnaryExpression(SqlUnaryExpression sqlUnaryExpression)
            {
                var result = base.VisitSqlUnaryExpression(sqlUnaryExpression);

                if (result is SqlUnaryExpression newUnaryExpression &&
                    newUnaryExpression.Operand is SqlParameterExpression parameterOperand)
                {
                    var parameterValue = _parametersValues[parameterOperand.Name];
                    if (sqlUnaryExpression.OperatorType == ExpressionType.Equal)
                    {
                        return(SqlExpressionFactory.Constant(parameterValue == null, sqlUnaryExpression.TypeMapping));
                    }

                    if (sqlUnaryExpression.OperatorType == ExpressionType.NotEqual)
                    {
                        return(SqlExpressionFactory.Constant(parameterValue != null, sqlUnaryExpression.TypeMapping));
                    }
                }

                return(result);
            }