diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerObjectToStringTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerObjectToStringTranslator.cs index c810ff4819d..67baec12504 100644 --- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerObjectToStringTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerObjectToStringTranslator.cs @@ -108,13 +108,15 @@ public SqlServerObjectToStringTranslator(ISqlExpressionFactory sqlExpressionFact // Enums are handled by EnumMethodTranslator return TypeMapping.TryGetValue(instance.Type, out var storeType) - ? _sqlExpressionFactory.Function( - "CONVERT", - new[] { _sqlExpressionFactory.Fragment(storeType), instance }, - nullable: true, - argumentsPropagateNullability: new[] { false, true }, - typeof(string), - _typeMappingSource.GetMapping(storeType)) + ? _sqlExpressionFactory.Coalesce( + _sqlExpressionFactory.Function( + "CONVERT", + new[] { _sqlExpressionFactory.Fragment(storeType), instance }, + nullable: true, + argumentsPropagateNullability: new[] { false, true }, + typeof(string), + _typeMappingSource.GetMapping(storeType)), + _sqlExpressionFactory.Constant(string.Empty)) : null; } } diff --git a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs index 0d62dcc57cf..6a241630b27 100644 --- a/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs +++ b/src/EFCore.Sqlite.Core/Query/Internal/Translators/SqliteObjectToStringTranslator.cs @@ -103,7 +103,9 @@ public SqliteObjectToStringTranslator(ISqlExpressionFactory sqlExpressionFactory // Enums are handled by EnumMethodTranslator return TypeMapping.Contains(instance.Type) - ? _sqlExpressionFactory.Convert(instance, typeof(string)) + ? _sqlExpressionFactory.Coalesce( + _sqlExpressionFactory.Convert(instance, typeof(string)), + _sqlExpressionFactory.Constant(string.Empty)) : null; } } diff --git a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs index 7bf55a39bee..b013d393c5c 100644 --- a/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs @@ -1019,18 +1019,7 @@ public virtual Task Update_Where_Join_set_property_from_joined_single_result_tab e => e.c, s => s.SetProperty(c => c.c.City, c => c.LastOrder.OrderDate.Value.Year.ToString()), rowsAffectedCount: 8, - (b, a) => Assert.All( - a, c => - { - if (c.CustomerID == "FISSA") - { - Assert.Null(c.City); - } - else - { - Assert.NotNull(c.City); - } - })); + (b, a) => Assert.All(a, c => Assert.NotNull(c.City))); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] @@ -1055,18 +1044,7 @@ public virtual Task Update_Where_Join_set_property_from_joined_single_result_sca e => e.c, s => s.SetProperty(c => c.c.City, c => c.LastOrderDate.ToString()), rowsAffectedCount: 8, - (b, a) => Assert.All( - a, c => - { - if (c.CustomerID == "FISSA") - { - Assert.Null(c.City); - } - else - { - Assert.NotNull(c.City); - } - })); + (b, a) => Assert.All(a, c => Assert.NotNull(c.City))); [ConditionalTheory] [MemberData(nameof(IsAsyncData))] diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs index 5ad9edf7ed3..e973a55ab36 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqlServerTest.cs @@ -120,7 +120,7 @@ public override async Task Update_owned_and_non_owned_properties_with_table_shar """ UPDATE [o] SET [o].[OwnedReference_Number] = CAST(LEN([o].[Title]) AS int), - [o].[Title] = CONVERT(varchar(11), [o].[OwnedReference_Number]) + [o].[Title] = COALESCE(CONVERT(varchar(11), [o].[OwnedReference_Number]), '') FROM [Owner] AS [o] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs index 7490c030160..dc962065b0c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs @@ -1414,11 +1414,11 @@ public override async Task Update_Where_Join_set_property_from_joined_single_res AssertExecuteUpdateSql( """ UPDATE [c] -SET [c].[City] = CONVERT(varchar(11), DATEPART(year, ( +SET [c].[City] = COALESCE(CONVERT(varchar(11), DATEPART(year, ( SELECT TOP(1) [o].[OrderDate] FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID] - ORDER BY [o].[OrderDate] DESC))) + ORDER BY [o].[OrderDate] DESC))), '') FROM [Customers] AS [c] WHERE [c].[CustomerID] LIKE N'F%' """); @@ -1449,11 +1449,11 @@ public override async Task Update_Where_Join_set_property_from_joined_single_res AssertExecuteUpdateSql( """ UPDATE [c] -SET [c].[City] = CONVERT(varchar(11), DATEPART(year, ( +SET [c].[City] = COALESCE(CONVERT(varchar(11), DATEPART(year, ( SELECT TOP(1) [o].[OrderDate] FROM [Orders] AS [o] WHERE [c].[CustomerID] = [o].[CustomerID] - ORDER BY [o].[OrderDate] DESC))) + ORDER BY [o].[OrderDate] DESC))), '') FROM [Customers] AS [c] WHERE [c].[CustomerID] LIKE N'F%' """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServerTest.cs index deaa0264de9..37d00a9cd21 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServerTest.cs @@ -840,9 +840,9 @@ await AssertQueryScalar( AssertSql( """ -SELECT CAST(ISDATE(CONVERT(varchar(100), [o].[OrderDate])) AS bit) +SELECT CAST(ISDATE(COALESCE(CONVERT(varchar(100), [o].[OrderDate]), '')) AS bit) FROM [Orders] AS [o] -WHERE CAST(ISDATE(CONVERT(varchar(100), [o].[OrderDate])) AS bit) = CAST(1 AS bit) +WHERE CAST(ISDATE(COALESCE(CONVERT(varchar(100), [o].[OrderDate]), '')) AS bit) = CAST(1 AS bit) """); } @@ -888,9 +888,9 @@ await AssertQueryScalar( AssertSql( """ -SELECT CAST(ISNUMERIC(CONVERT(varchar(100), [o].[OrderDate])) ^ 1 AS bit) ^ CAST(1 AS bit) +SELECT CAST(ISNUMERIC(COALESCE(CONVERT(varchar(100), [o].[OrderDate]), '')) ^ 1 AS bit) ^ CAST(1 AS bit) FROM [Orders] AS [o] -WHERE ISNUMERIC(CONVERT(varchar(100), [o].[OrderDate])) <> 1 +WHERE ISNUMERIC(COALESCE(CONVERT(varchar(100), [o].[OrderDate]), '')) <> 1 """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs index d88fe6eedeb..ef9132bcc54 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindMiscellaneousQuerySqlServerTest.cs @@ -3436,7 +3436,7 @@ public override async Task Query_expression_with_to_string_and_contains(bool asy """ SELECT [o].[CustomerID] FROM [Orders] AS [o] -WHERE [o].[OrderDate] IS NOT NULL AND CONVERT(varchar(10), [o].[EmployeeID]) LIKE '%7%' +WHERE [o].[OrderDate] IS NOT NULL AND COALESCE(CONVERT(varchar(10), [o].[EmployeeID]), '') LIKE '%7%' """); } @@ -3488,7 +3488,7 @@ public override async Task Select_expression_other_to_string(bool async) AssertSql( """ -SELECT CONVERT(varchar(100), [o].[OrderDate]) AS [ShipName] +SELECT COALESCE(CONVERT(varchar(100), [o].[OrderDate]), '') AS [ShipName] FROM [Orders] AS [o] WHERE [o].[OrderDate] IS NOT NULL """); diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs index 57c8c3b6c10..6809d2912e7 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesSqliteTest.cs @@ -118,7 +118,7 @@ public override async Task Update_owned_and_non_owned_properties_with_table_shar """ UPDATE "Owner" AS "o" SET "OwnedReference_Number" = length("o"."Title"), - "Title" = CAST("o"."OwnedReference_Number" AS TEXT) + "Title" = COALESCE(CAST("o"."OwnedReference_Number" AS TEXT), '') """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs index c277ffed4f2..39516e4e8b4 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs @@ -1328,12 +1328,12 @@ public override async Task Update_Where_Join_set_property_from_joined_single_res AssertExecuteUpdateSql( """ UPDATE "Customers" AS "c" -SET "City" = CAST(CAST(strftime('%Y', ( +SET "City" = COALESCE(CAST(CAST(strftime('%Y', ( SELECT "o"."OrderDate" FROM "Orders" AS "o" WHERE "c"."CustomerID" = "o"."CustomerID" ORDER BY "o"."OrderDate" DESC - LIMIT 1)) AS INTEGER) AS TEXT) + LIMIT 1)) AS INTEGER) AS TEXT), '') WHERE "c"."CustomerID" LIKE 'F%' """); } @@ -1362,12 +1362,12 @@ public override async Task Update_Where_Join_set_property_from_joined_single_res AssertExecuteUpdateSql( """ UPDATE "Customers" AS "c" -SET "City" = CAST(CAST(strftime('%Y', ( +SET "City" = COALESCE(CAST(CAST(strftime('%Y', ( SELECT "o"."OrderDate" FROM "Orders" AS "o" WHERE "c"."CustomerID" = "o"."CustomerID" ORDER BY "o"."OrderDate" DESC - LIMIT 1)) AS INTEGER) AS TEXT) + LIMIT 1)) AS INTEGER) AS TEXT), '') WHERE "c"."CustomerID" LIKE 'F%' """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs index 0690d3b81de..1dcb58c4e58 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs @@ -28,7 +28,7 @@ public override async Task Query_expression_with_to_string_and_contains(bool asy """ SELECT "o"."CustomerID" FROM "Orders" AS "o" -WHERE "o"."OrderDate" IS NOT NULL AND instr(CAST("o"."EmployeeID" AS TEXT), '7') > 0 +WHERE "o"."OrderDate" IS NOT NULL AND instr(COALESCE(CAST("o"."EmployeeID" AS TEXT), ''), '7') > 0 """); }