Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow SqlFragmentExpression to have Type/type mapping #33053

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/EFCore.Relational/Query/ISqlExpressionFactory.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -454,6 +452,15 @@ public interface ISqlExpressionFactory
/// <returns>An expression representing a constant in a SQL tree.</returns>
SqlConstantExpression Constant(object? value, Type type, RelationalTypeMapping? typeMapping = null);

/// <summary>
/// Creates a new <see cref="SqlFragmentExpression" /> which represents a SQL token.
/// </summary>
/// <param name="sql">A string token to print in SQL tree.</param>
/// <param name="type">The <see cref="Type" /> of the expression.</param>
/// <param name="typeMapping">The <see cref="RelationalTypeMapping" /> associated with the expression.</param>
/// <returns>An expression representing a SQL token.</returns>
SqlFragmentExpression Fragment(string sql, Type type, RelationalTypeMapping? typeMapping = null);

/// <summary>
/// Creates a new <see cref="SqlFragmentExpression" /> which represents a SQL token.
/// </summary>
Expand Down
6 changes: 5 additions & 1 deletion src/EFCore.Relational/Query/SqlExpressionFactory.cs
Expand Up @@ -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),
Expand Down Expand Up @@ -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));

/// <inheritdoc />
public virtual SqlFragmentExpression Fragment(string sql, Type type, RelationalTypeMapping? typeMapping = null)
=> new(sql, type, typeMapping);

/// <inheritdoc />
public virtual SqlFragmentExpression Fragment(string sql)
=> new(sql);
Expand Down
Expand Up @@ -19,7 +19,18 @@ public class SqlFragmentExpression : SqlExpression
/// </summary>
/// <param name="sql">A string token to print in SQL tree.</param>
public SqlFragmentExpression(string sql)
: base(typeof(string), null)
: this(sql, typeof(string), typeMapping: null)
{
}

/// <summary>
/// Creates a new instance of the <see cref="SqlFragmentExpression" /> class.
/// </summary>
/// <param name="sql">A string token to print in SQL tree.</param>
/// <param name="type">The <see cref="Type" /> of the expression.</param>
/// <param name="typeMapping">The <see cref="RelationalTypeMapping" /> associated with the expression.</param>
public SqlFragmentExpression(string sql, Type type, RelationalTypeMapping? typeMapping = null)
: base(type, typeMapping)
{
Sql = sql;
}
Expand All @@ -29,6 +40,14 @@ public SqlFragmentExpression(string sql)
/// </summary>
public virtual string Sql { get; }

/// <summary>
/// Applies supplied type mapping to this expression.
/// </summary>
/// <param name="typeMapping">A relational type mapping to apply.</param>
/// <returns>A new expression which has supplied type mapping.</returns>
public virtual SqlFragmentExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping)
=> new(Sql, Type, typeMapping);

/// <inheritdoc />
protected override Expression VisitChildren(ExpressionVisitor visitor)
=> this;
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore/Query/ExpressionPrinter.cs
Expand Up @@ -619,7 +619,7 @@ protected override Expression VisitMemberInit(MemberInitExpression memberInitExp
_stringBuilder.Append("new " + memberInitExpression.Type.ShortDisplayName());

var appendAction = memberInitExpression.Bindings.Count > 1 ? (Func<string, ExpressionVisitor>)AppendLine : Append;
appendAction("{ ");
appendAction(" { ");
using (_stringBuilder.Indent())
{
for (var i = 0; i < memberInitExpression.Bindings.Count; i++)
Expand Down Expand Up @@ -790,7 +790,7 @@ protected override Expression VisitNew(NewExpression newExpression)
}
else
{
appendAction("{ ");
appendAction(" { ");
}

IDisposable? indent = null;
Expand Down