diff --git a/src/EFCore.Relational/Query/QuerySqlGenerator.cs b/src/EFCore.Relational/Query/QuerySqlGenerator.cs
index d05ffa71cb3..f57e880b956 100644
--- a/src/EFCore.Relational/Query/QuerySqlGenerator.cs
+++ b/src/EFCore.Relational/Query/QuerySqlGenerator.cs
@@ -338,7 +338,7 @@ protected override Expression VisitTable(TableExpression tableExpression)
private void GenerateFromSql(FromSqlExpression fromSqlExpression)
{
var sql = fromSqlExpression.Sql;
- string[]? substitutions = null;
+ string[]? substitutions;
switch (fromSqlExpression.Arguments)
{
@@ -430,7 +430,7 @@ protected virtual void CheckComposableSql(string sql)
{
var i = span.IndexOf('\n');
span = i > 0
- ? span.Slice(i + 1).TrimStart()
+ ? span[(i + 1)..].TrimStart()
: throw new InvalidOperationException(RelationalStrings.FromSqlNonComposable);
continue;
}
@@ -440,7 +440,7 @@ protected virtual void CheckComposableSql(string sql)
{
var i = span.IndexOf("*/");
span = i > 0
- ? span.Slice(i + 2).TrimStart()
+ ? span[(i + 2)..].TrimStart()
: throw new InvalidOperationException(RelationalStrings.FromSqlNonComposable);
continue;
}
@@ -459,18 +459,11 @@ protected virtual void CheckComposableSql(string sql)
/// The given SQL isn't composable.
protected virtual void CheckComposableSqlTrimmed(ReadOnlySpan sql)
{
- if (sql.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
- {
- sql = sql.Slice("SELECT".Length);
- }
- else if (sql.StartsWith("WITH", StringComparison.OrdinalIgnoreCase))
- {
- sql = sql.Slice("WITH".Length);
- }
- else
- {
- throw new InvalidOperationException(RelationalStrings.FromSqlNonComposable);
- }
+ sql = sql.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase)
+ ? sql["SELECT".Length..]
+ : sql.StartsWith("WITH", StringComparison.OrdinalIgnoreCase)
+ ? sql["WITH".Length..]
+ : throw new InvalidOperationException(RelationalStrings.FromSqlNonComposable);
if (sql.Length > 0
&& (char.IsWhiteSpace(sql[0]) || sql.StartsWith("--") || sql.StartsWith("/*")))
@@ -484,7 +477,7 @@ protected virtual void CheckComposableSqlTrimmed(ReadOnlySpan sql)
///
protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpression)
{
- var requiresBrackets = RequiresBrackets(sqlBinaryExpression.Left);
+ var requiresBrackets = RequiresParentheses(sqlBinaryExpression, sqlBinaryExpression.Left);
if (requiresBrackets)
{
@@ -500,7 +493,7 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres
_relationalCommandBuilder.Append(GetOperator(sqlBinaryExpression));
- requiresBrackets = RequiresBrackets(sqlBinaryExpression.Right);
+ requiresBrackets = RequiresParentheses(sqlBinaryExpression, sqlBinaryExpression.Right);
if (requiresBrackets)
{
@@ -517,14 +510,6 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres
return sqlBinaryExpression;
}
- private static bool RequiresBrackets(SqlExpression expression)
- => expression is SqlBinaryExpression
- || expression is LikeExpression
- || (expression is SqlUnaryExpression unary
- && unary.Operand.Type == typeof(bool)
- && (unary.OperatorType == ExpressionType.Equal
- || unary.OperatorType == ExpressionType.NotEqual));
-
///
protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression)
{
@@ -661,7 +646,7 @@ protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpressio
case ExpressionType.Convert:
{
_relationalCommandBuilder.Append("CAST(");
- var requiresBrackets = RequiresBrackets(sqlUnaryExpression.Operand);
+ var requiresBrackets = RequiresParentheses(sqlUnaryExpression, sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append("(");
@@ -712,7 +697,7 @@ protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpressio
case ExpressionType.Negate:
{
_relationalCommandBuilder.Append("-");
- var requiresBrackets = RequiresBrackets(sqlUnaryExpression.Operand);
+ var requiresBrackets = RequiresParentheses(sqlUnaryExpression, sqlUnaryExpression.Operand);
if (requiresBrackets)
{
_relationalCommandBuilder.Append("(");
@@ -790,6 +775,56 @@ protected override Expression VisitIn(InExpression inExpression)
protected virtual string GetOperator(SqlBinaryExpression binaryExpression)
=> _operatorMap[binaryExpression.OperatorType];
+ ///
+ /// Returns a bool value indicating if the inner SQL expression required to be put inside parenthesis
+ /// when generating SQL for outer SQL expression.
+ ///
+ /// The outer expression which provides context in which SQL is being generated.
+ /// The inner expression which may need to be put inside parenthesis.
+ /// A bool value indicating that parenthesis is required or not.
+ protected virtual bool RequiresParentheses(SqlExpression outerExpression, SqlExpression innerExpression)
+ {
+ switch (innerExpression)
+ {
+ case LikeExpression _:
+ return true;
+
+ case SqlUnaryExpression sqlUnaryExpression:
+ {
+ // Wrap IS (NOT) NULL operation when applied on bool column.
+ if ((sqlUnaryExpression.OperatorType == ExpressionType.Equal
+ || sqlUnaryExpression.OperatorType == ExpressionType.NotEqual)
+ && sqlUnaryExpression.Operand.Type == typeof(bool))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ case SqlBinaryExpression sqlBinaryExpression:
+ {
+ //if (outerExpression is SqlBinaryExpression outerBinary)
+ //{
+ // if (outerBinary.OperatorType == ExpressionType.AndAlso)
+ // {
+ // return sqlBinaryExpression.OperatorType == ExpressionType.OrElse;
+ // }
+
+ // if (outerBinary.OperatorType == ExpressionType.OrElse)
+ // {
+ // // Precedence-wise AND is above OR but we still add parenthesis for ease of understanding
+ // return sqlBinaryExpression.OperatorType == ExpressionType.AndAlso;
+ // }
+ //}
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
///
/// Generates a TOP construct in the relational command
///
diff --git a/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs
index 0d42f118b72..5cf3f4c6df7 100644
--- a/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/LazyLoadProxySqlServerTest.cs
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
+using System.IO;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.TestUtilities;
@@ -20,161 +22,141 @@ public override void Lazy_load_collection(EntityState state, bool useAttach, boo
{
base.Lazy_load_collection(state, useAttach, useDetach);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707' (Nullable = true)
SELECT [c].[Id], [c].[ParentId]
FROM [Child] AS [c]
-WHERE [c].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [c].[ParentId] = @__p_0");
}
public override void Lazy_load_many_to_one_reference_to_principal(EntityState state, bool useAttach, bool useDetach)
{
base.Lazy_load_many_to_one_reference_to_principal(state, useAttach, useDetach);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_principal(EntityState state, bool useAttach, bool useDetach)
{
base.Lazy_load_one_to_one_reference_to_principal(state, useAttach, useDetach);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_dependent(EntityState state, bool useAttach, bool useDetach)
{
base.Lazy_load_one_to_one_reference_to_dependent(state, useAttach, useDetach);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707' (Nullable = true)
SELECT [s].[Id], [s].[ParentId]
FROM [Single] AS [s]
-WHERE [s].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [s].[ParentId] = @__p_0");
}
public override void Lazy_load_one_to_one_PK_to_PK_reference_to_principal(EntityState state)
{
base.Lazy_load_one_to_one_PK_to_PK_reference_to_principal(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_PK_to_PK_reference_to_dependent(EntityState state)
{
base.Lazy_load_one_to_one_PK_to_PK_reference_to_dependent(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707'
SELECT [s].[Id]
FROM [SinglePkToPk] AS [s]
-WHERE [s].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [s].[Id] = @__p_0");
}
public override void Lazy_load_many_to_one_reference_to_principal_null_FK(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_null_FK(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_reference_to_principal_null_FK(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_null_FK(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_collection_not_found(EntityState state)
{
base.Lazy_load_collection_not_found(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='767' (Nullable = true)
SELECT [c].[Id], [c].[ParentId]
FROM [Child] AS [c]
-WHERE [c].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [c].[ParentId] = @__p_0");
}
public override void Lazy_load_many_to_one_reference_to_principal_not_found(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_not_found(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='787'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_principal_not_found(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_not_found(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='787'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_dependent_not_found(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_dependent_not_found(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='767' (Nullable = true)
SELECT [s].[Id], [s].[ParentId]
FROM [Single] AS [s]
-WHERE [s].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [s].[ParentId] = @__p_0");
}
public override void Lazy_load_collection_already_loaded(EntityState state, CascadeTiming cascadeDeleteTiming)
{
base.Lazy_load_collection_already_loaded(state, cascadeDeleteTiming);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_many_to_one_reference_to_principal_already_loaded(
@@ -183,14 +165,14 @@ public override void Lazy_load_many_to_one_reference_to_principal_already_loaded
{
base.Lazy_load_many_to_one_reference_to_principal_already_loaded(state, cascadeDeleteTiming);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_reference_to_principal_already_loaded(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_already_loaded(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_reference_to_dependent_already_loaded(
@@ -199,221 +181,199 @@ public override void Lazy_load_one_to_one_reference_to_dependent_already_loaded(
{
base.Lazy_load_one_to_one_reference_to_dependent_already_loaded(state, cascadeDeleteTiming);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_PK_to_PK_reference_to_principal_already_loaded(EntityState state)
{
base.Lazy_load_one_to_one_PK_to_PK_reference_to_principal_already_loaded(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_PK_to_PK_reference_to_dependent_already_loaded(EntityState state)
{
base.Lazy_load_one_to_one_PK_to_PK_reference_to_dependent_already_loaded(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_many_to_one_reference_to_principal_alternate_key(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_alternate_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[AlternateId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[AlternateId] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_principal_alternate_key(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_alternate_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[AlternateId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[AlternateId] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_dependent_alternate_key(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_dependent_alternate_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
SELECT [s].[Id], [s].[ParentId]
FROM [SingleAk] AS [s]
-WHERE [s].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [s].[ParentId] = @__p_0");
}
public override void Lazy_load_many_to_one_reference_to_principal_null_FK_alternate_key(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_null_FK_alternate_key(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_reference_to_principal_null_FK_alternate_key(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_null_FK_alternate_key(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_collection_shadow_fk(EntityState state)
{
base.Lazy_load_collection_shadow_fk(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707' (Nullable = true)
SELECT [c].[Id], [c].[ParentId]
FROM [ChildShadowFk] AS [c]
-WHERE [c].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [c].[ParentId] = @__p_0");
}
public override void Lazy_load_many_to_one_reference_to_principal_shadow_fk(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_shadow_fk(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_principal_shadow_fk(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_shadow_fk(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE [p].[Id] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__p_0");
}
public override void Lazy_load_one_to_one_reference_to_dependent_shadow_fk(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_dependent_shadow_fk(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='707' (Nullable = true)
SELECT [s].[Id], [s].[ParentId]
FROM [SingleShadowFk] AS [s]
-WHERE [s].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [s].[ParentId] = @__p_0");
}
public override void Lazy_load_many_to_one_reference_to_principal_null_FK_shadow_fk(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_null_FK_shadow_fk(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_reference_to_principal_null_FK_shadow_fk(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_null_FK_shadow_fk(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_collection_composite_key(EntityState state)
{
base.Lazy_load_collection_composite_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
@__p_1='707' (Nullable = true)
SELECT [c].[Id], [c].[ParentAlternateId], [c].[ParentId]
FROM [ChildCompositeKey] AS [c]
-WHERE ([c].[ParentAlternateId] = @__p_0) AND ([c].[ParentId] = @__p_1)",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE ([c].[ParentAlternateId] = @__p_0) AND ([c].[ParentId] = @__p_1)");
}
public override void Lazy_load_many_to_one_reference_to_principal_composite_key(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_composite_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
@__p_1='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE ([p].[AlternateId] = @__p_0) AND ([p].[Id] = @__p_1)",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE ([p].[AlternateId] = @__p_0) AND ([p].[Id] = @__p_1)");
}
public override void Lazy_load_one_to_one_reference_to_principal_composite_key(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_composite_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
@__p_1='707'
SELECT [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
-WHERE ([p].[AlternateId] = @__p_0) AND ([p].[Id] = @__p_1)",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE ([p].[AlternateId] = @__p_0) AND ([p].[Id] = @__p_1)");
}
public override void Lazy_load_one_to_one_reference_to_dependent_composite_key(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_dependent_composite_key(state);
- Assert.Equal(
+ AssertSql(
@"@__p_0='Root' (Size = 450)
@__p_1='707' (Nullable = true)
SELECT [s].[Id], [s].[ParentAlternateId], [s].[ParentId]
FROM [SingleCompositeKey] AS [s]
-WHERE ([s].[ParentAlternateId] = @__p_0) AND ([s].[ParentId] = @__p_1)",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE ([s].[ParentAlternateId] = @__p_0) AND ([s].[ParentId] = @__p_1)");
}
public override void Lazy_load_many_to_one_reference_to_principal_null_FK_composite_key(EntityState state)
{
base.Lazy_load_many_to_one_reference_to_principal_null_FK_composite_key(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override void Lazy_load_one_to_one_reference_to_principal_null_FK_composite_key(EntityState state)
{
base.Lazy_load_one_to_one_reference_to_principal_null_FK_composite_key(state);
- Assert.Equal("", Sql);
+ AssertSql(@"");
}
public override async Task Load_collection(EntityState state, bool async)
@@ -422,14 +382,12 @@ public override async Task Load_collection(EntityState state, bool async)
if (!async)
{
- Assert.Equal(
+ AssertSql(
@"@__p_0='707' (Nullable = true)
SELECT [c].[Id], [c].[ParentId]
FROM [Child] AS [c]
-WHERE [c].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [c].[ParentId] = @__p_0");
}
}
@@ -438,7 +396,7 @@ public override void Top_level_projection_track_entities_before_passing_to_clien
{
base.Top_level_projection_track_entities_before_passing_to_client_method();
- Assert.Equal(
+ AssertSql(
@"SELECT TOP(1) [p].[Id], [p].[AlternateId], [p].[Discriminator]
FROM [Parent] AS [p]
ORDER BY [p].[Id]
@@ -447,24 +405,20 @@ ORDER BY [p].[Id]
SELECT [s].[Id], [s].[ParentId]
FROM [Single] AS [s]
-WHERE [s].[ParentId] = @__p_0",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [s].[ParentId] = @__p_0");
}
public override async Task Entity_equality_with_proxy_parameter(bool async)
{
await base.Entity_equality_with_proxy_parameter(async);
- Assert.Equal(
+ AssertSql(
@"@__entity_equality_called_0_Id='707' (Nullable = true)
SELECT [c].[Id], [c].[ParentId]
FROM [Child] AS [c]
LEFT JOIN [Parent] AS [p] ON [c].[ParentId] = [p].[Id]
-WHERE [p].[Id] = @__entity_equality_called_0_Id",
- Sql,
- ignoreLineEndingDifferences: true);
+WHERE [p].[Id] = @__entity_equality_called_0_Id");
}
protected override void ClearLog()
@@ -473,6 +427,51 @@ protected override void ClearLog()
protected override void RecordLog()
=> Sql = Fixture.TestSqlLoggerFactory.Sql;
+ private const string FileNewLine = @"
+";
+
+ private void AssertSql(string expected)
+ {
+ try
+ {
+ Assert.Equal(
+ expected, Sql, ignoreLineEndingDifferences: true);
+ }
+ catch
+ {
+ var methodCallLine = Environment.StackTrace.Split(
+ new[] { Environment.NewLine },
+ StringSplitOptions.RemoveEmptyEntries)[2][6..];
+
+ var indexMethodEnding = methodCallLine.IndexOf(')') + 1;
+ var testName = methodCallLine.Substring(0, indexMethodEnding);
+ var parts = methodCallLine[indexMethodEnding..].Split(" ", StringSplitOptions.RemoveEmptyEntries);
+ var fileName = parts[1][..^5];
+ var lineNumber = int.Parse(parts[2]);
+
+ var currentDirectory = Directory.GetCurrentDirectory();
+ var logFile = currentDirectory.Substring(
+ 0,
+ currentDirectory.LastIndexOf(
+ $"{Path.DirectorySeparatorChar}artifacts{Path.DirectorySeparatorChar}",
+ StringComparison.Ordinal) + 1)
+ + "QueryBaseline.txt";
+
+ var testInfo = testName + " : " + lineNumber + FileNewLine;
+ var newBaseLine = $@" AssertSql(
+ {"@\"" + Sql.Replace("\"", "\"\"") + "\""});
+
+";
+
+ var contents = testInfo + newBaseLine + FileNewLine + "--------------------" + FileNewLine;
+
+ File.AppendAllText(logFile, contents);
+
+ throw;
+ }
+ }
+
+
private string Sql { get; set; }
public class LoadSqlServerFixture : LoadFixtureBase
diff --git a/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs
index e0fc14186b8..8ceb2fd8495 100644
--- a/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/LoadSqlServerTest.cs
@@ -1463,9 +1463,7 @@ private void AssertSql(string expected)
try
{
Assert.Equal(
- expected,
- Sql,
- ignoreLineEndingDifferences: true);
+ expected, Sql, ignoreLineEndingDifferences: true);
}
catch
{
@@ -1473,24 +1471,27 @@ private void AssertSql(string expected)
new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries)[2][6..];
- var testName = methodCallLine.Substring(0, methodCallLine.IndexOf(')') + 1);
- var lineIndex = methodCallLine.LastIndexOf("line", StringComparison.Ordinal);
- var lineNumber = lineIndex > 0 ? methodCallLine[lineIndex..] : "";
+ var indexMethodEnding = methodCallLine.IndexOf(')') + 1;
+ var testName = methodCallLine.Substring(0, indexMethodEnding);
+ var parts = methodCallLine[indexMethodEnding..].Split(" ", StringSplitOptions.RemoveEmptyEntries);
+ var fileName = parts[1][..^5];
+ var lineNumber = int.Parse(parts[2]);
var currentDirectory = Directory.GetCurrentDirectory();
var logFile = currentDirectory.Substring(
0,
- currentDirectory.LastIndexOf("\\artifacts\\", StringComparison.Ordinal) + 1)
+ currentDirectory.LastIndexOf(
+ $"{Path.DirectorySeparatorChar}artifacts{Path.DirectorySeparatorChar}",
+ StringComparison.Ordinal) + 1)
+ "QueryBaseline.txt";
var testInfo = testName + " : " + lineNumber + FileNewLine;
-
var newBaseLine = $@" AssertSql(
{"@\"" + Sql.Replace("\"", "\"\"") + "\""});
";
- var contents = testInfo + newBaseLine + FileNewLine + FileNewLine;
+ var contents = testInfo + newBaseLine + FileNewLine + "--------------------" + FileNewLine;
File.AppendAllText(logFile, contents);