Skip to content

Commit

Permalink
Allow SqlFragmentExpression to have Type/type mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
roji committed Feb 10, 2024
1 parent 581b7c0 commit 860eb6d
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
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

0 comments on commit 860eb6d

Please sign in to comment.