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); }
/// <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); }
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); }
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(); }
/// <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); }
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); }
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); }
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(); }
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)); }