diff --git a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs index fabab2bb19d..35499e85961 100644 --- a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; namespace Microsoft.EntityFrameworkCore.Query; @@ -454,6 +452,15 @@ public interface ISqlExpressionFactory /// An expression representing a constant in a SQL tree. SqlConstantExpression Constant(object? value, Type type, RelationalTypeMapping? typeMapping = null); + /// + /// Creates a new which represents a SQL token. + /// + /// A string token to print in SQL tree. + /// The of the expression. + /// The associated with the expression. + /// An expression representing a SQL token. + SqlFragmentExpression Fragment(string sql, Type type, RelationalTypeMapping? typeMapping = null); + /// /// Creates a new which represents a SQL token. /// diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index 0dbfacce2d1..b6d09d18506 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -64,7 +64,7 @@ public SqlExpressionFactory(SqlExpressionFactoryDependencies dependencies) ScalarSubqueryExpression e => e.ApplyTypeMapping(typeMapping), SqlBinaryExpression e => ApplyTypeMappingOnSqlBinary(e, typeMapping), SqlConstantExpression e => e.ApplyTypeMapping(typeMapping), - SqlFragmentExpression e => e, + SqlFragmentExpression e => e.ApplyTypeMapping(typeMapping), SqlFunctionExpression e => e.ApplyTypeMapping(typeMapping), SqlParameterExpression e => e.ApplyTypeMapping(typeMapping), SqlUnaryExpression e => ApplyTypeMappingOnSqlUnary(e, typeMapping), @@ -688,6 +688,10 @@ public virtual InExpression In(SqlExpression item, SqlParameterExpression values public virtual LikeExpression Like(SqlExpression match, SqlExpression pattern, SqlExpression? escapeChar = null) => (LikeExpression)ApplyDefaultTypeMapping(new LikeExpression(match, pattern, escapeChar, null)); + /// + public virtual SqlFragmentExpression Fragment(string sql, Type type, RelationalTypeMapping? typeMapping = null) + => new(sql, type, typeMapping); + /// public virtual SqlFragmentExpression Fragment(string sql) => new(sql); diff --git a/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs index bc867cc8b92..855459e33be 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SqlFragmentExpression.cs @@ -19,7 +19,18 @@ public class SqlFragmentExpression : SqlExpression /// /// A string token to print in SQL tree. public SqlFragmentExpression(string sql) - : base(typeof(string), null) + : this(sql, typeof(string), typeMapping: null) + { + } + + /// + /// Creates a new instance of the class. + /// + /// A string token to print in SQL tree. + /// The of the expression. + /// The associated with the expression. + public SqlFragmentExpression(string sql, Type type, RelationalTypeMapping? typeMapping = null) + : base(type, typeMapping) { Sql = sql; } @@ -29,6 +40,14 @@ public SqlFragmentExpression(string sql) /// public virtual string Sql { get; } + /// + /// Applies supplied type mapping to this expression. + /// + /// A relational type mapping to apply. + /// A new expression which has supplied type mapping. + public SqlFragmentExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping) + => new(Sql, Type, typeMapping); + /// protected override Expression VisitChildren(ExpressionVisitor visitor) => this;