diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
index 717d31dad4f..64c4d282642 100644
--- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
+++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs
@@ -200,6 +200,43 @@ protected override Expression VisitValues(ValuesExpression valuesExpression)
return valuesExpression;
}
+ ///
+ /// 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.
+ ///
+ protected override Expression VisitSqlFunction(SqlFunctionExpression sqlFunctionExpression)
+ {
+ if (sqlFunctionExpression is { IsBuiltIn: true, Arguments: not null }
+ && string.Equals(sqlFunctionExpression.Name, "COALESCE", StringComparison.OrdinalIgnoreCase))
+ {
+ var head = sqlFunctionExpression.Arguments[0];
+ if (head.TypeMapping != sqlFunctionExpression.TypeMapping)
+ {
+ head = new SqlUnaryExpression(
+ ExpressionType.Convert,
+ head,
+ sqlFunctionExpression.Type,
+ sqlFunctionExpression.TypeMapping);
+ }
+
+ sqlFunctionExpression = (SqlFunctionExpression)sqlFunctionExpression
+ .Arguments
+ .Skip(1)
+ .Aggregate(head, (l, r) => new SqlFunctionExpression(
+ "ISNULL",
+ arguments: [l, r],
+ nullable: true,
+ argumentsPropagateNullability: [false, false],
+ sqlFunctionExpression.Type,
+ sqlFunctionExpression.TypeMapping
+ ));
+ }
+
+ return base.VisitSqlFunction(sqlFunctionExpression);
+ }
+
///
/// 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