internal SqlClientWhen(SqlExpression match, SqlExpression value) { // 'match' may be null when this when represents the ELSE condition. if (value == null) throw Error.ArgumentNull("value"); this.Match = match; this.Value = value; }
internal override SqlExpression ConvertPredicateToValue(SqlExpression predicateExpression) { // Transform the 'Predicate' expression into a 'Bit' by forming the // following operation: // CASE // WHEN predicateExpression THEN 1 // ELSE NOT(predicateExpression) THEN 0 // ELSE NULL // END // Possible simplification to the generated SQL would be to detect when 'predicateExpression' // is SqlUnary(NOT) and use its operand with the literal 1 and 0 below swapped. SqlExpression valueTrue = sql.ValueFromObject(true, false, predicateExpression.SourceExpression); SqlExpression valueFalse = sql.ValueFromObject(false, false, predicateExpression.SourceExpression); if (SqlExpressionNullability.CanBeNull(predicateExpression) != false) { SqlExpression valueNull = sql.Value(valueTrue.ClrType, valueTrue.SqlType, null, false, predicateExpression.SourceExpression); return new SqlSearchedCase( predicateExpression.ClrType, new SqlWhen[] { new SqlWhen(predicateExpression, valueTrue), new SqlWhen(new SqlUnary(SqlNodeType.Not, predicateExpression.ClrType, predicateExpression.SqlType, predicateExpression, predicateExpression.SourceExpression), valueFalse) }, valueNull, predicateExpression.SourceExpression ); } else { return new SqlSearchedCase( predicateExpression.ClrType, new SqlWhen[] { new SqlWhen(predicateExpression, valueTrue) }, valueFalse, predicateExpression.SourceExpression ); } }
internal override SqlNode Visit(SqlNode node) { if (node == null) return null; sourceExpression = node as SqlExpression; if (sourceExpression != null) { Type type = sourceExpression.ClrType; UnwrapStack unwrap = this.UnwrapSequences; while (unwrap != null) { if (unwrap.Unwrap) { type = TypeSystem.GetElementType(type); } unwrap = unwrap.Last; } sourceType = type; } if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType) { return node; // Value types can't also have a dynamic type. } if (sourceType != null && TypeSystem.HasIEnumerable(sourceType)) { return node; // Sequences can't be polymorphic. } switch (node.NodeType) { case SqlNodeType.ScalarSubSelect: case SqlNodeType.Multiset: case SqlNodeType.Element: case SqlNodeType.SearchedCase: case SqlNodeType.ClientCase: case SqlNodeType.SimpleCase: case SqlNodeType.Member: case SqlNodeType.DiscriminatedType: case SqlNodeType.New: case SqlNodeType.FunctionCall: case SqlNodeType.MethodCall: case SqlNodeType.Convert: // Object identity does not survive convert. It does survive Cast. // Dig no further. return node; case SqlNodeType.TypeCase: sourceType = ((SqlTypeCase)node).RowType.Type; return node; case SqlNodeType.Link: sourceType = ((SqlLink)node).RowType.Type; return node; case SqlNodeType.Table: sourceType = ((SqlTable)node).RowType.Type; return node; case SqlNodeType.Value: SqlValue val = (SqlValue)node; if (val.Value != null) { // In some cases the ClrType of a Value node may // differ from the actual runtime type of the value. // Therefore, we ensure here that the correct type is set. sourceType = val.Value.GetType(); } return node; } return base.Visit(node); }
/// <summary> /// Renders IfNull SqlExpression /// </summary> /// <param name="builder"></param> /// <param name="expr"></param> protected override void IfNull(StringBuilder builder, SqlExpression expr) { builder.Append("ifnull("); Expression(builder, expr.SubExpr1); builder.Append(", "); Expression(builder, expr.SubExpr2); builder.Append(")"); }
internal override SqlNode VisitLink(SqlLink link) { SqlExpression expansion = this.VisitExpression(link.Expansion); SqlExpression[] exprs = new SqlExpression[link.KeyExpressions.Count]; for (int i = 0, n = exprs.Length; i < n; i++) { exprs[i] = this.VisitExpression(link.KeyExpressions[i]); } return new SqlLink(link.Id, link.RowType, link.ClrType, link.SqlType, link.Expression, link.Member, exprs, expansion, link.SourceExpression); }
public IExpressionBuilder Function(ObjectName functionName, params SqlExpression[] args) { expression = SqlExpression.FunctionCall(functionName, args); VerifyUnary(); return this; }
public IExpressionBuilder Quantified(SqlExpressionType quantifyType, Action<IExpressionBuilder> exp) { var builder = new ExpressionBuilder(); exp(builder); expression = SqlExpression.Quantified(quantifyType, builder.Build()); return this; }
public IExpressionBuilder Query(Action<IQueryExpressionBuilder> query) { var builder = new QueryExpressionBuilder(); query(builder); expression = builder.Build(); return this; }
public override void SetTable(SqlTable table, MemberInfo member, IEnumerable<Expression> expArgs, IEnumerable<ISqlExpression> sqlArgs) { var aargs = sqlArgs.ToArray(); var arr = ConvertArgs(member, aargs).ToList(); var method = (MethodInfo)member; { var ttype = method.GetGenericArguments()[0]; var tbl = new SqlTable(ttype); var database = Convert(tbl.Database); var owner = Convert(tbl.Owner); var physicalName = Convert(tbl.PhysicalName); var name = ""; if (database != null) name = database + "." + (owner == null ? "." : owner + "."); else if (owner != null) name = owner + "."; name += physicalName; arr.Add(new SqlExpression(name, Precedence.Primary)); } { var field = ((ConstantExpression)expArgs.First()).Value; if (field is string) { arr[0] = new SqlExpression(field.ToString(), Precedence.Primary); } else if (field is LambdaExpression) { var body = ((LambdaExpression)field).Body; if (body is MemberExpression) { var name = ((MemberExpression)body).Member.Name; if (name.Length > 0 && name[0] != '[') name = "[" + name + "]"; arr[0] = new SqlExpression(name, Precedence.Primary); } } } table.SqlTableType = SqlTableType.Expression; table.Name = "FREETEXTTABLE({6}, {2}, {3}) {1}"; table.TableArguments = arr.ToArray(); }
// returns CONVERT(VARCHAR/NVARCHAR/VARBINARY(MAX), expr) if provType is one of Text, NText or Image // otherwise just returns expr // changed is true if CONVERT(...(MAX),...) was added private SqlExpression ConvertToMax(SqlExpression expr, out bool changed) { changed = false; if (!expr.SqlType.IsLargeType) return expr; ProviderType newType = sql.TypeProvider.GetBestLargeType(expr.SqlType); changed = true; if (expr.SqlType != newType) { return ConvertToMax(expr, newType); } changed = false; return expr; }
/// <summary> /// Renders SqlExpression /// </summary> /// <param name="builder"></param> /// <param name="expr"></param> protected override void Expression(StringBuilder builder, SqlExpression expr) { SqlExpressionType type = expr.Type; if (type == SqlExpressionType.Field) { QualifiedIdentifier(builder, expr.TableAlias, expr.Value.ToString()); } else if (type == SqlExpressionType.Function) { Function(builder, expr.AggFunction, expr.SubExpr1); } else if (type == SqlExpressionType.Constant) { Constant(builder, (SqlConstant) expr.Value); } else if (type == SqlExpressionType.SubQueryText) { builder.AppendFormat("({0})", (string) expr.Value); } else if (type == SqlExpressionType.SubQueryObject) { builder.AppendFormat("({0})", RenderSelect((SelectQuery) expr.Value)); } else if (type == SqlExpressionType.PseudoField) { builder.AppendFormat("{0}", (string) expr.Value); } else if (type == SqlExpressionType.Parameter) { builder.AppendFormat("{0}", (string) expr.Value); } else if (type == SqlExpressionType.LikeExpressionParameter) { builder.AppendFormat("'%' + {0} + '%'", (string) expr.Value); } else if (type == SqlExpressionType.Raw) { builder.AppendFormat("{0}", (string) expr.Value); } else if (type == SqlExpressionType.IfNull) { IfNull(builder, expr); } else if (type == SqlExpressionType.Null) { builder.Append("null"); } else { throw new InvalidQueryException("Unkown expression type: " + type.ToString()); } }
internal override SqlExpression ConvertValueToPredicate(SqlExpression valueExpression) { // Transform the 'Bit' expression into a 'Predicate' by forming the // following operation: // OriginalExpr = 1 // Yukon and later could also handle: // OriginalExpr = 'true' // but Sql2000 does not support this. return new SqlBinary(SqlNodeType.EQ, valueExpression.ClrType, sql.TypeProvider.From(typeof(bool)), valueExpression, sql.Value(typeof(bool), valueExpression.SqlType, true, false, valueExpression.SourceExpression) ); }
public IExpressionBuilder Binary(SqlExpressionType binaryType, Action<IExpressionBuilder> right) { if (expression == null) throw new InvalidOperationException(); var builder = new ExpressionBuilder(); right(builder); expression = SqlExpression.Binary(expression, binaryType, builder.Build()); VerifyUnary(); return this; }
/// <summary> /// Helper for VisitBinaryOperator. Builds the new case with distributed valueds. /// </summary> private SqlExpression DistributeOperatorIntoCase(SqlNodeType nt, SqlSimpleCase sc, SqlExpression expr) { if (nt!=SqlNodeType.EQ && nt!=SqlNodeType.NE && nt!=SqlNodeType.EQ2V && nt!=SqlNodeType.NE2V) throw Error.ArgumentOutOfRange("nt"); object val = Eval(expr); List<SqlExpression> values = new List<SqlExpression>(); List<SqlExpression> matches = new List<SqlExpression>(); foreach(SqlWhen when in sc.Whens) { matches.Add(when.Match); object whenVal = Eval(when.Value); bool eq = when.Value.SqlType.AreValuesEqual(whenVal, val); values.Add(sql.ValueFromObject((nt==SqlNodeType.EQ || nt==SqlNodeType.EQ2V) == eq, false, sc.SourceExpression)); } return this.VisitExpression(sql.Case(typeof(bool), sc.Expression, matches, values, sc.SourceExpression)); }
protected string InferName(SqlExpression exp, string def) { if (exp == null) return null; SqlExpressionType nodeType = exp.NodeType; switch (nodeType) { case SqlExpressionType.Field: return ((SqlField)exp).Name; case SqlExpressionType.Alias: return InferName(((SqlAlias)exp).Expression, def); case SqlExpressionType.ExprSet: return InferName(((SqlExpressionSet)exp).First(), def); } return def; }
protected void AddParentheses(SqlExpression node, SqlExpression outer) { switch (node.NodeType) { case SqlExpressionType.Function: case SqlExpressionType.TableValuedFunction: case SqlExpressionType.Raw: case SqlExpressionType.Parameter: case SqlExpressionType.Constant: case SqlExpressionType.Variable: case SqlExpressionType.Field: Visit(node); break; case SqlExpressionType.Binary: SqlBinary binary = (SqlBinary)node; switch (binary.Operation) { case SqlBinaryOperation.Add: case SqlBinaryOperation.And: case SqlBinaryOperation.BitAnd: case SqlBinaryOperation.BitNot: case SqlBinaryOperation.BitOr: case SqlBinaryOperation.BitXor: case SqlBinaryOperation.Multiply: case SqlBinaryOperation.Or: if (node.NodeType == outer.NodeType) Visit(node); break; default: _builder.Append('('); Visit(node); _builder.Append(')'); break; } break; default: _builder.Append('('); Visit(node); _builder.Append(')'); break; } }
internal SqlExpression ConvertTo(Type clrType, SqlExpression expr) { // // In SQL Server 2008, the new TIME data type cannot be converted to BIGINT, or FLOAT, // or a bunch of other SQL types. // if (clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(Nullable<>)) clrType = clrType.GetGenericArguments()[0]; bool isClrTimeSpanType = clrType == typeof(TimeSpan); if (IsSqlTimeType(expr)) { if (isClrTimeSpanType) { // no conversion necessary return expr; } else { expr = ConvertToDateTime(expr); } } return UnaryConvert(clrType, typeProvider.From(clrType), expr, expr.SourceExpression); }
public override void SetTable(MappingSchema mappingSchema, SqlTable table, MemberInfo member, IEnumerable<Expression> expArgs, IEnumerable<ISqlExpression> sqlArgs) { var method = member as MethodInfo; if (method == null) throw new ArgumentNullException("member"); var paramsList = method.GetParameters().ToList(); var valuesList = expArgs.Cast<ConstantExpression>().ToList(); if (paramsList.Count != valuesList.Count) throw new TargetParameterCountException("Invalid number of parameters"); var sqlValues = new List<ISqlExpression>(); for(var i = 0; i < paramsList.Count; i++) { var val = valuesList[i].Value; if (val == null) continue; var p = paramsList[i]; sqlValues.Add(new SqlValue("$$" + p.Name + "$$")); sqlValues.Add(new SqlValue(ValueToString(val))); } var arg = new ISqlExpression[1]; arg[0] = new SqlExpression( String.Join(", ", Enumerable.Range(0, sqlValues.Count) .Select(x => "{" + x + "}")), sqlValues.ToArray()); table.SqlTableType = SqlTableType.Expression; table.Name = "{0}('PLACEHOLDER' = {2}) {1}"; table.TableArguments = arg.ToArray(); }
internal SqlExpression BuildProjection(SqlExpression item, MetaType rowType, bool allowDeferred, SqlLink link, Expression source) { if (!rowType.HasInheritance) { return this.BuildProjectionInternal(item, rowType, (rowType.Table != null) ? rowType.PersistentDataMembers : rowType.DataMembers, allowDeferred, link, source); } else { // Build a type case that represents a switch between the various type. List<MetaType> mappedTypes = new List<MetaType>(rowType.InheritanceTypes); List<SqlTypeCaseWhen> whens = new List<SqlTypeCaseWhen>(); SqlTypeCaseWhen @else = null; MetaType root = rowType.InheritanceRoot; MetaDataMember discriminator = root.Discriminator; Type dt = discriminator.Type; SqlMember dm = sql.Member(item, discriminator.Member); foreach (MetaType type in mappedTypes) { if (type.HasInheritanceCode) { SqlNew defaultProjection = this.BuildProjectionInternal(item, type, type.PersistentDataMembers, allowDeferred, link, source); if (type.IsInheritanceDefault) { @else = new SqlTypeCaseWhen(null, defaultProjection); } // Add an explicit case even for the default. // Redundant results will be optimized out later. object code = InheritanceRules.InheritanceCodeForClientCompare(type.InheritanceCode, dm.SqlType); SqlExpression match = sql.Value(dt, sql.Default(discriminator), code, true, source); whens.Add(new SqlTypeCaseWhen(match, defaultProjection)); } } if (@else == null) { throw Error.EmptyCaseNotSupported(); } whens.Add(@else); // Add the else at the end. return sql.TypeCase(root.Type, root, dm, whens.ToArray(), source); } }
/// <summary> /// Visits the specified <see cref="SqlExpression"/>. /// </summary> /// <param name="expression"> /// The expression to visit. /// </param> public virtual void Visit(SqlExpression expression) { switch (expression.ExpressionType) { case SqlExpressionType.Assign: Visit((SqlAssign)expression); break; case SqlExpressionType.Binary: Visit((SqlBinaryExpression)expression); break; case SqlExpressionType.Column: Visit((SqlColumn)expression); break; case SqlExpressionType.Constant: Visit((SqlConstant)expression); break; case SqlExpressionType.Delete: Visit((SqlDelete)expression); break; case SqlExpressionType.Limit: Visit((SqlLimit)expression); break; case SqlExpressionType.From: Visit((SqlFrom)expression); break; case SqlExpressionType.Function: Visit((SqlFunction)expression); break; case SqlExpressionType.Identifier: Visit((SqlIdentifier)expression); break; case SqlExpressionType.Insert: Visit((SqlInsert)expression); break; case SqlExpressionType.Join: Visit((SqlJoin)expression); break; case SqlExpressionType.On: Visit((SqlOn)expression); break; case SqlExpressionType.OrderBy: Visit((SqlOrderBy)expression); break; case SqlExpressionType.GroupBy: Visit((SqlGroupBy)expression); break; case SqlExpressionType.Having: Visit((SqlHaving)expression); break; case SqlExpressionType.Parameter: Visit((SqlParameter)expression); break; case SqlExpressionType.Select: Visit((SqlSelect)expression); break; case SqlExpressionType.Sort: Visit((SqlSort)expression); break; case SqlExpressionType.Subquery: Visit((SqlSubquery)expression); break; case SqlExpressionType.Table: Visit((SqlTable)expression); break; case SqlExpressionType.Union: Visit((SqlUnion)expression); break; case SqlExpressionType.Update: Visit((SqlUpdate)expression); break; case SqlExpressionType.ValueList: Visit((SqlValueList)expression); break; case SqlExpressionType.Values: Visit((SqlValues)expression); break; case SqlExpressionType.Where: Visit((SqlWhere)expression); break; case SqlExpressionType.Into: Visit((SqlInto)expression); break; case SqlExpressionType.Set: Visit((SqlSet)expression); break; default: throw new InvalidOperationException("Unknown type of expression found."); } }
private void CoerceToFirst(SqlExpression arg1, ref SqlExpression arg2) { if (arg1.SqlType != null && arg2.SqlType != null) { if (arg2.NodeType == SqlNodeType.Value) { SqlValue val = (SqlValue)arg2; arg2 = sql.Value( arg1.ClrType, arg1.SqlType, DBConvert.ChangeType(val.Value, arg1.ClrType), val.IsClientSpecified, arg2.SourceExpression ); } else if (arg2.NodeType == SqlNodeType.ClientParameter && arg2.SqlType != arg1.SqlType) { SqlClientParameter cp = (SqlClientParameter)arg2; cp.SetSqlType(arg1.SqlType); } else { arg2 = sql.UnaryConvert(arg1.ClrType, arg1.SqlType, arg2, arg2.SourceExpression); } } }
public virtual MySqlJsonArrayIndexExpression JsonArrayIndex( [NotNull] SqlExpression expression) => JsonArrayIndex(expression, typeof(int));
internal abstract SqlExpression ConvertPredicateToValue(SqlExpression predicateExpression);
public IAsyncQueryProvider <T> WhereSql(string sql, params object[] args) { _sqlExpression = _sqlExpression.Where(sql, args); return(this); }
public MySqlStringComparisonMethodTranslator(ISqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = (MySqlSqlExpressionFactory)sqlExpressionFactory; _caseSensitiveComparisons = _sqlExpressionFactory.Constant( new[] { StringComparison.Ordinal, StringComparison.CurrentCulture, StringComparison.InvariantCulture }); }
private void CoerceTypes(ref SqlExpression arg1, ref SqlExpression arg2) { if (arg2.NodeType == SqlNodeType.Value) { arg2 = CoerceValueForExpression((SqlValue)arg2, arg1); } else if (arg1.NodeType == SqlNodeType.Value) { arg1 = CoerceValueForExpression((SqlValue)arg1, arg2); } else if (arg2.NodeType == SqlNodeType.ClientParameter && arg2.SqlType != arg1.SqlType) { ((SqlClientParameter)arg2).SetSqlType(arg1.SqlType); } else if (arg1.NodeType == SqlNodeType.ClientParameter && arg1.SqlType != arg2.SqlType) { ((SqlClientParameter)arg1).SetSqlType(arg2.SqlType); } else { int coercionPrecedence = arg1.SqlType.ComparePrecedenceTo(arg2.SqlType); if (coercionPrecedence > 0) { arg2 = sql.UnaryConvert(arg1.ClrType, arg1.SqlType, arg2, arg2.SourceExpression); } else if (coercionPrecedence < 0) { arg1 = sql.UnaryConvert(arg2.ClrType, arg2.SqlType, arg1, arg1.SourceExpression); } } }
public IAsyncQueryProvider <T> Limit(int skip, int rows) { ThrowIfOneToMany(); _sqlExpression = _sqlExpression.Limit(skip, rows); return(this); }
private bool RequiresBrackets(SqlExpression expression) { return(expression is SqlBinaryExpression sqlBinary && sqlBinary.OperatorType != ExpressionType.Coalesce || expression is LikeExpression); }
private SqlExpression BuildCompareToExpression(SqlExpression sqlExpression) { return(_sqlExpressionFactory.Equal(sqlExpression, _sqlExpressionFactory.Constant(true))); }
private static bool RequiresBrackets(SqlExpression expression) => expression is SqlBinaryExpression || expression is LikeExpression;
// !(?a) != b -> (a == b) || (a == null) // // a | b | F1 = a == b | F2 = (a == null) | F3 = F1 OR F2 | // | | | | | // 0 | 0 | 1 | 0 | 1 | // 0 | 1 | 0 | 0 | 0 | // 1 | 0 | 0 | 0 | 0 | // 1 | 1 | 1 | 0 | 1 | // N | 0 | N | 1 | 1 | // N | 1 | N | 1 | 1 | private SqlBinaryExpression ExpandNegatedNullableNotEqualNonNullable( SqlExpression left, SqlExpression right, SqlExpression leftIsNull) => _sqlExpressionFactory.OrElse( _sqlExpressionFactory.Equal(left, right), leftIsNull);
// !(?a) == b -> (a != b) && (a != null) // // a | b | F1 = a != b | F2 = (a != null) | Final = F1 && F2 | // | | | | | // 0 | 0 | 0 | 1 | 0 | // 0 | 1 | 1 | 1 | 1 | // 1 | 0 | 1 | 1 | 1 | // 1 | 1 | 0 | 1 | 0 | // N | 0 | N | 0 | 0 | // N | 1 | N | 0 | 0 | private SqlBinaryExpression ExpandNegatedNullableEqualNonNullable( SqlExpression left, SqlExpression right, SqlExpression leftIsNull) => _sqlExpressionFactory.AndAlso( _sqlExpressionFactory.NotEqual(left, right), _sqlExpressionFactory.Not(leftIsNull));
private void CoerceTypeFamily(SqlExpression arg1, SqlExpression arg2) { if ((arg1.SqlType.HasPrecisionAndScale && arg2.SqlType.HasPrecisionAndScale && arg1.SqlType != arg2.SqlType) || SqlFactory.IsSqlHighPrecisionDateTimeType(arg1) || SqlFactory.IsSqlHighPrecisionDateTimeType(arg2)) { ProviderType best = typeProvider.GetBestType(arg1.SqlType, arg2.SqlType); SetSqlTypeIfSimpleExpression(arg1, best); SetSqlTypeIfSimpleExpression(arg2, best); return; } // The SQL data type DATE is special, in that it has a higher range but lower // precedence, so we need to account for that here (DevDiv 175229) if (SqlFactory.IsSqlDateType(arg1) && !SqlFactory.IsSqlHighPrecisionDateTimeType(arg2)) { SetSqlTypeIfSimpleExpression(arg2, arg1.SqlType); } else if (SqlFactory.IsSqlDateType(arg2) && !SqlFactory.IsSqlHighPrecisionDateTimeType(arg1)) { SetSqlTypeIfSimpleExpression(arg1, arg2.SqlType); } }
public PagingObject <T> Paging(SqlExpression <T> query, int pageIndex, int pageSize) { return(_repository.Paging(query, pageIndex, pageSize)); }
public SimpleSelectNode(IQueryPlanNode child, ObjectName columnName, SqlExpressionType op, SqlExpression expression) : base(child) { ColumnName = columnName; OperatorType = op; Expression = expression; }
private Expression ConvertToSearchCondition(SqlExpression sqlExpression, bool condition) => condition ? sqlExpression : BuildCompareToExpression(sqlExpression);
public IAsyncQueryProvider <T> WhereSql(Sql sql) { _sqlExpression = _sqlExpression.Where(sql.SQL, sql.Arguments); return(this); }
private Expression ApplyConversion(SqlExpression sqlExpression, bool condition) => _isSearchCondition ? ConvertToSearchCondition(sqlExpression, condition) : ConvertToValue(sqlExpression, condition);
public IAsyncQueryProvider <T> Where(Expression <Func <T, bool> > whereExpression) { _sqlExpression = _sqlExpression.Where(whereExpression); return(this); }
private static string GetProviderType(SqlExpression expression) { return(expression.TypeMapping?.StoreType); }
private SqlExpression MakeStartsWithEndsWithExpressionImpl( SqlExpression target, [NotNull] Func <SqlExpression, SqlExpression> targetTransform, SqlExpression prefixSuffix, [NotNull] Func <SqlExpression, SqlExpression> prefixSuffixTransform, bool startsWith) { var stringTypeMapping = ExpressionExtensions.InferTypeMapping(target, prefixSuffix); target = _sqlExpressionFactory.ApplyTypeMapping(target, stringTypeMapping); prefixSuffix = _sqlExpressionFactory.ApplyTypeMapping(prefixSuffix, stringTypeMapping); if (prefixSuffix is SqlConstantExpression constantPrefixSuffixExpression) { // The prefix is constant. Aside from null or empty, we escape all special characters (%, _, \) // in C# and send a simple LIKE. if (constantPrefixSuffixExpression.Value is string constantPrefixSuffixString) { // TRUE (pattern == "") // something LIKE 'foo%' (pattern != "", StartsWith()) // something LIKE '%foo' (pattern != "", EndsWith()) return(constantPrefixSuffixString == string.Empty ? (SqlExpression)_sqlExpressionFactory.Constant(true) : _sqlExpressionFactory.Like( targetTransform(target), prefixSuffixTransform( _sqlExpressionFactory.Constant( (startsWith ? string.Empty : "%") + EscapeLikePattern(constantPrefixSuffixString) + (startsWith ? "%" : string.Empty))))); } // https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/996#issuecomment-607876040 // Can return NULL in .NET 5 after https://github.com/dotnet/efcore/issues/20498 has been fixed. // `something LIKE NULL` always returns `NULL`. We will return `false`, to indicate, that no match // could be found, because returning a constant of `NULL` will throw later in EF Core when used as // a predicate. // return _sqlExpressionFactory.Constant(null, RelationalTypeMapping.NullMapping); // This results in NULL anyway, but works around EF Core's inability to handle predicates that are // constant null values. return(_sqlExpressionFactory.Like(target, _sqlExpressionFactory.Constant(null, stringTypeMapping))); } // TODO: Generally, LEFT & compare is faster than escaping potential pattern characters with REPLACE(). // However, this might not be the case, if the pattern is constant after all (e.g. `LCASE('fo%o')`), in // which case, `something LIKE CONCAT(REPLACE(REPLACE(LCASE('fo%o'), '%', '\\%'), '_', '\\_'), '%')` should // be faster than `LEFT(something, CHAR_LENGTH('fo%o')) = LCASE('fo%o')`. // See https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/996#issuecomment-607733553 // The prefix is non-constant, we use LEFT to extract the substring and compare. return(_sqlExpressionFactory.Equal( _sqlExpressionFactory.Function( startsWith ? "LEFT" : "RIGHT", new[] { targetTransform(target), CharLength(prefixSuffix) }, typeof(string), stringTypeMapping), prefixSuffixTransform(prefixSuffix))); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); SqlExpression modifier = null; if (_addMilliseconds.Equals(method)) { modifier = _sqlExpressionFactory.Add( _sqlExpressionFactory.Convert( _sqlExpressionFactory.Divide( arguments[0], _sqlExpressionFactory.Constant(1000.0)), typeof(string)), _sqlExpressionFactory.Constant(" seconds")); } else if (_addTicks.Equals(method)) { modifier = _sqlExpressionFactory.Add( _sqlExpressionFactory.Convert( _sqlExpressionFactory.Divide( arguments[0], _sqlExpressionFactory.Constant((double)TimeSpan.TicksPerDay)), typeof(string)), _sqlExpressionFactory.Constant(" seconds")); } else if (_methodInfoToUnitSuffix.TryGetValue(method, out var unitSuffix)) { modifier = _sqlExpressionFactory.Add( _sqlExpressionFactory.Convert(arguments[0], typeof(string)), _sqlExpressionFactory.Constant(unitSuffix)); } if (modifier != null) { return(_sqlExpressionFactory.Function( "rtrim", new SqlExpression[] { _sqlExpressionFactory.Function( "rtrim", new SqlExpression[] { SqliteExpression.Strftime( _sqlExpressionFactory, method.ReturnType, "%Y-%m-%d %H:%M:%f", instance, new[] { modifier }), _sqlExpressionFactory.Constant("0") }, nullResultAllowed: true, argumentsPropagateNullability: new[] { true, false }, method.ReturnType), _sqlExpressionFactory.Constant(".") }, nullResultAllowed: true, argumentsPropagateNullability: new[] { true, false }, method.ReturnType)); } return(null); }
internal abstract SqlExpression ConvertValueToPredicate(SqlExpression valueExpression);
private static List <T> NacitatZoznam <T>(this IWebEasCoreRepositoryBase sourceType, SqlExpression <T> filter, string tenantId) where T : class { Guid filterTenantGuid; Type typEntity = typeof(T); if (typeof(ITenantEntity).IsAssignableFrom(typEntity)) { if (string.IsNullOrWhiteSpace(tenantId) || !Guid.TryParse(tenantId, out filterTenantGuid)) { return(new List <T>()); } filter.And <ITenantEntity>(f => f.D_Tenant_Id == filterTenantGuid); } else if (typeof(ITenantEntityNullable).IsAssignableFrom(typEntity)) { if (string.IsNullOrWhiteSpace(tenantId) || !Guid.TryParse(tenantId, out filterTenantGuid)) { return(new List <T>()); } filter.And <ITenantEntityNullable>(f => f.D_Tenant_Id == filterTenantGuid || f.D_Tenant_Id == null); } return(sourceType.Db.Select <T>(filter).ToList()); }
/// <summary> /// If an expression is type 'Bit' but a 'Predicate' is expected then /// call 'VisitBitExpectedPredicate'. /// </summary> internal SqlExpression VisitPredicate(SqlExpression exp) { exp = (SqlExpression)base.Visit(exp); if (exp != null) { if (!IsPredicateExpression(exp)) { exp = ConvertValueToPredicate(exp); } } return exp; }
private static void DeclareCursor(IQuery query) { var queryExp1 = (SqlQueryExpression)SqlExpression.Parse("SELECT * FROM APP.test_table"); query.Context.DeclareCursor("c1", queryExp1); }
private string InferName(SqlExpression exp, string def) { if (exp == null) return null; switch (exp.NodeType) { case SqlNodeType.Member: return ((SqlMember)exp).Member.Name; case SqlNodeType.Column: return ((SqlColumn)exp).Name; case SqlNodeType.ColumnRef: return ((SqlColumnRef)exp).Column.Name; case SqlNodeType.ExprSet: return this.InferName(((SqlExprSet)exp).Expressions[0], def); default: return def; } }
public IAsyncQueryProvider <T> ThenByDescending(Expression <Func <T, object> > column) { _sqlExpression = _sqlExpression.ThenByDescending(column); return(this); }
private void CoerceBinaryArgs(ref SqlExpression arg1, ref SqlExpression arg2) { if (arg1.SqlType == null || arg2.SqlType == null) return; if (arg1.SqlType.IsSameTypeFamily(arg2.SqlType)) { CoerceTypeFamily(arg1, arg2); } else { // Don't coerce bools because predicates and bits have not been resolved yet. // Leave this for booleanizer. if (arg1.ClrType != typeof(bool) && arg2.ClrType != typeof(bool)) { CoerceTypes(ref arg1, ref arg2); } } }
public IAsyncQueryProvider <T> OrderBy(Expression <Func <T, object> > column) { _sqlExpression = _sqlExpression.OrderBy(column); return(this); }
private static void SetSqlTypeIfSimpleExpression(SqlExpression expression, ProviderType sqlType) { SqlSimpleTypeExpression simpleExpression = expression as SqlSimpleTypeExpression; if (simpleExpression != null) { simpleExpression.SetSqlType(sqlType); } }
private static Type GetProviderType(SqlExpression expression) => (expression.TypeMapping?.Converter?.ProviderClrType ?? expression.TypeMapping?.ClrType ?? expression.Type).UnwrapNullableType();
private SqlExpression CoerceValueForExpression(SqlValue value, SqlExpression expression) { object clrValue = value.Value; if (!value.ClrType.IsAssignableFrom(expression.ClrType)) { clrValue = DBConvert.ChangeType(clrValue, expression.ClrType); } ProviderType newSqlType = typeProvider.ChangeTypeFamilyTo(value.SqlType, expression.SqlType); return sql.Value(expression.ClrType, newSqlType, clrValue, value.IsClientSpecified, value.SourceExpression); }
public async Task <PagingObject <T> > PagingAsync(SqlExpression <T> query, int pageIndex, int pageSize) { return(await _repository.PagingAsync(query, pageIndex, pageSize)); }