public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            Check.NotNull(method, nameof(method));
            Check.NotNull(arguments, nameof(arguments));

            if (method.IsGenericMethod &&
                method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains) &&
                ValidateValues(arguments[0]))
            {
                return(_sqlExpressionFactory.In(arguments[1], arguments[0], negated: false));
            }

            if (method.Name == nameof(IList.Contains) &&
                arguments.Count == 1 &&
                method.DeclaringType.GetInterfaces().Append(method.DeclaringType).Any(
                    t => t == typeof(IList) ||
                    (t.IsGenericType &&
                     t.GetGenericTypeDefinition() == typeof(ICollection <>))) &&
                ValidateValues(instance))
            {
                return(_sqlExpressionFactory.In(arguments[0], instance, negated: false));
            }

            return(null);
        }
예제 #2
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>
        public virtual SqlExpression?Translate(
            SqlExpression?instance,
            MethodInfo method,
            IReadOnlyList <SqlExpression> arguments,
            IDiagnosticsLogger <DbLoggerCategory.Query> logger)
        {
            Check.NotNull(method, nameof(method));
            Check.NotNull(arguments, nameof(arguments));
            Check.NotNull(logger, nameof(logger));

            if (method.IsGenericMethod &&
                method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains) &&
                ValidateValues(arguments[0]))
            {
                return(_sqlExpressionFactory.In(RemoveObjectConvert(arguments[1]), arguments[0], negated: false));
            }

            if (arguments.Count == 1 &&
                method.IsContainsMethod() &&
                instance != null &&
                ValidateValues(instance))
            {
                return(_sqlExpressionFactory.In(RemoveObjectConvert(arguments[0]), instance, negated: false));
            }

            return(null);
        }
예제 #3
0
        public SqlExpression Translate(SqlExpression instance, MethodInfo method, IList <SqlExpression> arguments)
        {
            if (method.IsGenericMethod &&
                method.GetGenericMethodDefinition().Equals(_containsMethod))
            {
                return(_sqlExpressionFactory.In(arguments[1], arguments[0], false));
            }
            else if (method.DeclaringType.GetInterfaces().Contains(typeof(IList)) &&
                     string.Equals(method.Name, nameof(IList.Contains)))
            {
                return(_sqlExpressionFactory.In(arguments[0], instance, false));
            }

            return(null);
        }
        protected override Expression VisitTypeBinary(TypeBinaryExpression 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 = BindProperty(entityProjectionExpression, 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);
        }
예제 #5
0
        protected override ShapedQueryExpression TranslateContains(ShapedQueryExpression source, Expression item)
        {
            var selectExpression = (SelectExpression)source.QueryExpression;
            var translation      = TranslateExpression(item);

            if (translation != null)
            {
                if (selectExpression.Limit == null &&
                    selectExpression.Offset == null)
                {
                    selectExpression.ClearOrdering();
                }

                selectExpression.ApplyProjection();
                translation = _sqlExpressionFactory.In(translation, selectExpression, false);
                var projectionMapping = new Dictionary <ProjectionMember, Expression>
                {
                    { new ProjectionMember(), translation }
                };

                source.QueryExpression = new SelectExpression(
                    "",
                    projectionMapping,
                    new List <ProjectionExpression>(),
                    new List <TableExpressionBase>());
                source.ShaperExpression = new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), typeof(bool));

                return(source);
            }

            throw new NotImplementedException();
        }
예제 #6
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>
        public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (method.IsGenericMethod &&
                method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains) &&
                ValidateValues(arguments[0]))
            {
                return(_sqlExpressionFactory.In(arguments[1], arguments[0], false));
            }

            if (arguments.Count == 1 &&
                method.IsContainsMethod() &&
                ValidateValues(instance))
            {
                return(_sqlExpressionFactory.In(arguments[0], instance, false));
            }

            return(null);
        }
예제 #7
0
        public virtual SqlExpression?Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (method.IsGenericMethod &&
                method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains))
            {
                return(_sqlExpressionFactory.In(arguments[1], arguments[0], false));
            }

            if ((method.DeclaringType.GetInterfaces().Contains(typeof(IList)) ||
                 method.DeclaringType.IsGenericType &&
                 method.DeclaringType.GetGenericTypeDefinition() == typeof(ICollection <>)) &&
                string.Equals(method.Name, nameof(IList.Contains)))
            {
                return(_sqlExpressionFactory.In(arguments[0], instance, false));
            }

            return(null);
        }
예제 #8
0
        public virtual SqlExpression?Translate(
            SqlExpression?instance,
            MethodInfo method,
            IReadOnlyList <SqlExpression> arguments,
            IDiagnosticsLogger <DbLoggerCategory.Query> logger)
        {
            if (method.IsGenericMethod &&
                method.GetGenericMethodDefinition().Equals(EnumerableMethods.Contains) &&
                ValidateValues(arguments[0]))
            {
                return(_sqlExpressionFactory.In(arguments[1], arguments[0], false));
            }

            if (arguments.Count == 1 &&
                method.IsContainsMethod() &&
                instance != null &&
                ValidateValues(instance))
            {
                return(_sqlExpressionFactory.In(arguments[0], instance, false));
            }

            return(null);
        }
예제 #9
0
        protected override ShapedQueryExpression TranslateContains(ShapedQueryExpression source, Expression item)
        {
            var selectExpression = (SelectExpression)source.QueryExpression;
            var translation      = TranslateExpression(item);

            if (translation != null)
            {
                if (selectExpression.Limit == null &&
                    selectExpression.Offset == null)
                {
                    selectExpression.ClearOrdering();
                }

                selectExpression.ApplyProjection();
                translation             = _sqlExpressionFactory.In(translation, selectExpression, false);
                source.QueryExpression  = selectExpression.SetProjectionAsResult(translation);
                source.ShaperExpression = new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), typeof(bool));

                return(source);
            }

            throw new NotImplementedException();
        }
예제 #10
0
            public override Expression Visit(Expression expression)
            {
                if (expression is InExpression inExpression &&
                    inExpression.Values != null)
                {
                    var inValues     = new List <object>();
                    var hasNullValue = false;
                    RelationalTypeMapping typeMapping = null;

                    switch (inExpression.Values)
                    {
                    case SqlConstantExpression sqlConstant:
                    {
                        typeMapping = sqlConstant.TypeMapping;
                        var values = (IEnumerable)sqlConstant.Value;
                        foreach (var value in values)
                        {
                            if (value == null)
                            {
                                hasNullValue = true;
                                continue;
                            }

                            inValues.Add(value);
                        }
                    }
                    break;

                    case SqlParameterExpression sqlParameter:
                    {
                        typeMapping = sqlParameter.TypeMapping;
                        var values = (IEnumerable)_parametersValues[sqlParameter.Name];
                        foreach (var value in values)
                        {
                            if (value == null)
                            {
                                hasNullValue = true;
                                continue;
                            }

                            inValues.Add(value);
                        }
                    }
                    break;
                    }

                    var updatedInExpression = inValues.Count > 0
                        ? _sqlExpressionFactory.In(
                        (SqlExpression)Visit(inExpression.Item),
                        _sqlExpressionFactory.Constant(inValues, typeMapping),
                        inExpression.Negated)
                        : null;

                    var nullCheckExpression = hasNullValue
                        ? inExpression.Negated
                            ? _sqlExpressionFactory.IsNotNull(inExpression.Item)
                            : _sqlExpressionFactory.IsNull(inExpression.Item)
                        : null;

                    if (updatedInExpression != null && nullCheckExpression != null)
                    {
                        return(inExpression.Negated
                            ? _sqlExpressionFactory.AndAlso(updatedInExpression, nullCheckExpression)
                            : _sqlExpressionFactory.OrElse(updatedInExpression, nullCheckExpression));
                    }

                    if (updatedInExpression == null && nullCheckExpression == null)
                    {
                        return(_sqlExpressionFactory.Equal(_sqlExpressionFactory.Constant(true), _sqlExpressionFactory.Constant(inExpression.Negated)));
                    }

                    return((SqlExpression)updatedInExpression ?? nullCheckExpression);
                }

                return(base.Visit(expression));
            }