diff --git a/src/EFCore.Relational/Query/Internal/SqlExpressionSimplifyingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/SqlExpressionSimplifyingExpressionVisitor.cs
index e262e1553b3..5514ae02d2a 100644
--- a/src/EFCore.Relational/Query/Internal/SqlExpressionSimplifyingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/SqlExpressionSimplifyingExpressionVisitor.cs
@@ -12,22 +12,10 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal;
/// 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.
///
-public class SqlExpressionSimplifyingExpressionVisitor : ExpressionVisitor
+public class SqlExpressionSimplifyingExpressionVisitor(
+ ISqlExpressionFactory _sqlExpressionFactory,
+ bool _useRelationalNulls) : ExpressionVisitor
{
- private readonly ISqlExpressionFactory _sqlExpressionFactory;
- private readonly bool _useRelationalNulls;
-
- ///
- /// 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.
- ///
- public SqlExpressionSimplifyingExpressionVisitor(ISqlExpressionFactory sqlExpressionFactory, bool useRelationalNulls)
- {
- _sqlExpressionFactory = sqlExpressionFactory;
- _useRelationalNulls = useRelationalNulls;
- }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -37,51 +25,66 @@ public SqlExpressionSimplifyingExpressionVisitor(ISqlExpressionFactory sqlExpres
///
protected override Expression VisitExtension(Expression extensionExpression)
{
- if (extensionExpression is ShapedQueryExpression shapedQueryExpression)
+ switch (extensionExpression)
{
- var newQueryExpression = Visit(shapedQueryExpression.QueryExpression);
- var newShaperExpression = Visit(shapedQueryExpression.ShaperExpression);
+ case ShapedQueryExpression shapedQueryExpression:
+ {
+ var newQueryExpression = Visit(shapedQueryExpression.QueryExpression);
+ var newShaperExpression = Visit(shapedQueryExpression.ShaperExpression);
- return shapedQueryExpression.Update(newQueryExpression, newShaperExpression);
- }
+ return shapedQueryExpression.Update(newQueryExpression, newShaperExpression);
+ }
- if (extensionExpression is SqlBinaryExpression sqlBinaryExpression)
- {
- return SimplifySqlBinary(sqlBinaryExpression);
- }
+ // Strip no-op SQL CASTs: when the Convert's store type matches the operand's store type,
+ // the CAST would be a no-op in SQL (e.g. CAST(column AS nvarchar(max)) when column is already nvarchar(max)).
+ // This can occur in various situations, e.g. when a C# implicit conversion exists for a value-converted type
+ // (see #36247 for more context on why we don't refrain from creating the CAST node during translation).
+ // However, CASTs around constants are preserved: they serve to explicitly type the constant in SQL
+ // (e.g. CAST(100 AS int)), which is important for some queries.
+ case SqlUnaryExpression
+ {
+ OperatorType: ExpressionType.Convert,
+ Operand: not SqlConstantExpression and { TypeMapping.StoreType: var operandStoreType } operand,
+ TypeMapping.StoreType: var convertStoreType
+ } when convertStoreType == operandStoreType:
+ return Visit(operand);
- if (extensionExpression is SqlFunctionExpression sqlFunctionExpression
- && IsCoalesce(sqlFunctionExpression))
- {
- var arguments = new List();
- foreach (var argument in sqlFunctionExpression.Arguments!)
+ case SqlBinaryExpression sqlBinaryExpression:
+ return SimplifySqlBinary(sqlBinaryExpression);
+
+ case SqlFunctionExpression sqlFunctionExpression when IsCoalesce(sqlFunctionExpression):
{
- var newArgument = (SqlExpression)Visit(argument);
- if (IsCoalesce(newArgument))
+ var arguments = new List();
+ foreach (var argument in sqlFunctionExpression.Arguments!)
{
- arguments.AddRange(((SqlFunctionExpression)newArgument).Arguments!);
- }
- else
- {
- arguments.Add(newArgument);
+ var newArgument = (SqlExpression)Visit(argument);
+ if (IsCoalesce(newArgument))
+ {
+ arguments.AddRange(((SqlFunctionExpression)newArgument).Arguments!);
+ }
+ else
+ {
+ arguments.Add(newArgument);
+ }
}
+
+ var distinctArguments = arguments.Distinct().ToList();
+
+ return distinctArguments.Count > 1
+ ? new SqlFunctionExpression(
+ sqlFunctionExpression.Name,
+ distinctArguments,
+ sqlFunctionExpression.IsNullable,
+ argumentsPropagateNullability: distinctArguments.Select(_ => false).ToArray(),
+ sqlFunctionExpression.Type,
+ sqlFunctionExpression.TypeMapping)
+ : distinctArguments[0];
}
- var distinctArguments = arguments.Distinct().ToList();
-
- return distinctArguments.Count > 1
- ? new SqlFunctionExpression(
- sqlFunctionExpression.Name,
- distinctArguments,
- sqlFunctionExpression.IsNullable,
- argumentsPropagateNullability: distinctArguments.Select(_ => false).ToArray(),
- sqlFunctionExpression.Type,
- sqlFunctionExpression.TypeMapping)
- : distinctArguments[0];
+ default:
+ return base.VisitExtension(extensionExpression);
}
- return base.VisitExtension(extensionExpression);
-
static bool IsCoalesce(SqlExpression sqlExpression)
=> sqlExpression is SqlFunctionExpression { IsBuiltIn: true, Instance: null } sqlFunctionExpression
&& string.Equals(sqlFunctionExpression.Name, "COALESCE", StringComparison.OrdinalIgnoreCase)
diff --git a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs
index a3842779cef..d374d326a89 100644
--- a/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs
+++ b/src/EFCore.SqlServer/Query/Internal/Translators/SqlServerIsDateFunctionTranslator.cs
@@ -33,7 +33,7 @@ public class SqlServerIsDateFunctionTranslator(ISqlExpressionFactory sqlExpressi
[arguments[1]],
nullable: true,
argumentsPropagateNullability: Statics.TrueArrays[1],
- method.ReturnType),
+ typeof(int)),
method.ReturnType)
: null;
}
diff --git a/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs
index dc54e970652..765ae28533e 100644
--- a/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs
@@ -349,6 +349,53 @@ public class BlogDetails
}
#endregion
+
+ #region 36247
+
+ [ConditionalTheory, MemberData(nameof(IsAsyncData))]
+ public virtual async Task Like_on_value_converted_string_column_does_not_produce_cast(bool async)
+ {
+ var contextFactory = await InitializeNonSharedTest(
+ seed: async ctx =>
+ {
+ ctx.Users.AddRange(
+ new Context36247.User { Name = new Context36247.FullName("Name1") },
+ new Context36247.User { Name = new Context36247.FullName("Name2") });
+ await ctx.SaveChangesAsync();
+ });
+ using var context = contextFactory.CreateDbContext();
+
+ var query = context.Users.Where(x => EF.Functions.Like(x.Name, "Name%"));
+
+ var result = async
+ ? await query.ToListAsync()
+ : [.. query];
+
+ Assert.Equal(2, result.Count);
+ }
+
+ protected class Context36247(DbContextOptions options) : DbContext(options)
+ {
+ public DbSet Users { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ => modelBuilder.Entity().Property(e => e.Name)
+ .HasConversion(v => v.Value, v => new FullName(v));
+
+ public class User
+ {
+ public int Id { get; set; }
+ public FullName Name { get; set; }
+ }
+
+ public readonly record struct FullName(string Value)
+ {
+ public static implicit operator string(FullName fullName)
+ => fullName.Value;
+ }
+ }
+
+ #endregion
}
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs
index 0dd131f150b..7a31744d3eb 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs
@@ -2211,7 +2211,7 @@ public override async Task Null_check_removal_in_ternary_maintain_appropriate_ca
AssertSql(
"""
-SELECT CAST([f].[Taste] AS tinyint) AS [Bar]
+SELECT [f].[Taste] AS [Bar]
FROM [Foods] AS [f]
""");
}
@@ -2668,6 +2668,18 @@ ELSE N'B'
END AS [Foo]
FROM [Data] AS [d]
ORDER BY [d].[Id]
+""");
+ }
+
+ public override async Task Like_on_value_converted_string_column_does_not_produce_cast(bool async)
+ {
+ await base.Like_on_value_converted_string_column_does_not_produce_cast(async);
+
+ AssertSql(
+ """
+SELECT [u].[Id], [u].[Name]
+FROM [Users] AS [u]
+WHERE [u].[Name] LIKE N'Name%'
""");
}
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
index 3251f548d5a..23cf3c03672 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
@@ -3546,7 +3546,7 @@ public override async Task ToString_enum_contains(bool async)
"""
SELECT [m].[CodeName]
FROM [Missions] AS [m]
-WHERE CAST([m].[Difficulty] AS nvarchar(max)) LIKE N'%Med%'
+WHERE [m].[Difficulty] LIKE N'%Med%'
""");
}
@@ -7429,7 +7429,7 @@ public override async Task Enum_flags_closure_typed_as_different_type_generates_
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
FROM [Gears] AS [g]
-WHERE @prm & CAST([g].[Rank] AS int) = CAST([g].[Rank] AS int)
+WHERE @prm & [g].[Rank] = [g].[Rank]
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPCGearsOfWarQuerySqlServerTest.cs
index ca1c14a3aa8..24c4cb80ef6 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPCGearsOfWarQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPCGearsOfWarQuerySqlServerTest.cs
@@ -4730,7 +4730,7 @@ public override async Task ToString_enum_contains(bool async)
"""
SELECT [m].[CodeName]
FROM [Missions] AS [m]
-WHERE CAST([m].[Difficulty] AS nvarchar(max)) LIKE N'%Med%'
+WHERE [m].[Difficulty] LIKE N'%Med%'
""");
}
@@ -9915,7 +9915,7 @@ UNION ALL
SELECT [o].[Nickname], [o].[SquadId], [o].[AssignedCityName], [o].[CityOfBirthName], [o].[FullName], [o].[HasSoulPatch], [o].[LeaderNickname], [o].[LeaderSquadId], [o].[Rank], N'Officer' AS [Discriminator]
FROM [Officers] AS [o]
) AS [u]
-WHERE @prm & CAST([u].[Rank] AS int) = CAST([u].[Rank] AS int)
+WHERE @prm & [u].[Rank] = [u].[Rank]
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPTGearsOfWarQuerySqlServerTest.cs
index 8ad0f930981..1c7ba920cee 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPTGearsOfWarQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/Inheritance/TPTGearsOfWarQuerySqlServerTest.cs
@@ -4139,7 +4139,7 @@ public override async Task ToString_enum_contains(bool async)
"""
SELECT [m].[CodeName]
FROM [Missions] AS [m]
-WHERE CAST([m].[Difficulty] AS nvarchar(max)) LIKE N'%Med%'
+WHERE [m].[Difficulty] LIKE N'%Med%'
""");
}
@@ -8377,7 +8377,7 @@ WHEN [o].[Nickname] IS NOT NULL THEN N'Officer'
END AS [Discriminator]
FROM [Gears] AS [g]
LEFT JOIN [Officers] AS [o] ON [g].[Nickname] = [o].[Nickname] AND [g].[SquadId] = [o].[SquadId]
-WHERE @prm & CAST([g].[Rank] AS int) = CAST([g].[Rank] AS int)
+WHERE @prm & [g].[Rank] = [g].[Rank]
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs
index a54443c7781..7d0e5c6d2f9 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSqlQuerySqlServerTest.cs
@@ -50,11 +50,11 @@ public override async Task SqlQuery_composed_Join(bool async)
AssertSql(
"""
-SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], CAST([s].[Value] AS int) AS [p]
+SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [s].[Value] AS [p]
FROM [Orders] AS [o]
INNER JOIN (
SELECT "ProductID" AS "Value" FROM "Products"
-) AS [s] ON [o].[OrderID] = CAST([s].[Value] AS int)
+) AS [s] ON [o].[OrderID] = [s].[Value]
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
index ceee9d5352f..b0f77b12b83 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs
@@ -449,7 +449,7 @@ public override async Task Inline_collection_with_single_parameter_element_Count
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE (
SELECT COUNT(*)
- FROM (VALUES (CAST(@i AS int))) AS [v]([Value])
+ FROM (VALUES (@i)) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 1
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
index 7973138146f..17898609540 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs
@@ -415,7 +415,7 @@ public override async Task Inline_collection_with_single_parameter_element_Count
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE (
SELECT COUNT(*)
- FROM (VALUES (CAST(@i AS int))) AS [v]([Value])
+ FROM (VALUES (@i)) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 1
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs
index 4545a3b982c..6bfe2463603 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs
@@ -48,7 +48,7 @@ public override async Task Inline_collection_with_single_parameter_element_Count
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE (
SELECT COUNT(*)
- FROM (VALUES (CAST(@i AS int))) AS [v]([Value])
+ FROM (VALUES (@i)) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 1
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs
index c9f5016ae5b..64048ab72ab 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs
@@ -443,7 +443,7 @@ public override async Task Inline_collection_with_single_parameter_element_Count
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE (
SELECT COUNT(*)
- FROM (VALUES (CAST(@i AS int))) AS [v]([Value])
+ FROM (VALUES (@i)) AS [v]([Value])
WHERE [v].[Value] > [p].[Id]) = 1
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs
index 50c6926534d..029f935662b 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs
@@ -4239,7 +4239,7 @@ public override async Task ToString_enum_contains(bool async)
"""
SELECT [m].[CodeName]
FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m]
-WHERE CAST([m].[Difficulty] AS nvarchar(max)) LIKE N'%Med%'
+WHERE [m].[Difficulty] LIKE N'%Med%'
""");
}
@@ -5350,7 +5350,7 @@ public override async Task Enum_flags_closure_typed_as_different_type_generates_
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank]
FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g]
-WHERE @prm & CAST([g].[Rank] AS int) = CAST([g].[Rank] AS int)
+WHERE @prm & [g].[Rank] = [g].[Rank]
""");
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs
index 292be557c2f..e2f133a76f6 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs
@@ -188,7 +188,7 @@ public override async Task FromTimeSpan_compared_to_property()
"""
SELECT [b].[Id], [b].[Bool], [b].[Byte], [b].[ByteArray], [b].[DateOnly], [b].[DateTime], [b].[DateTimeOffset], [b].[Decimal], [b].[Double], [b].[Enum], [b].[FlagsEnum], [b].[Float], [b].[Guid], [b].[Int], [b].[Long], [b].[Short], [b].[String], [b].[TimeOnly], [b].[TimeSpan]
FROM [BasicTypesEntities] AS [b]
-WHERE CAST([b].[TimeSpan] AS time) < [b].[TimeOnly]
+WHERE [b].[TimeSpan] < [b].[TimeOnly]
""");
}
@@ -202,7 +202,7 @@ public override async Task FromTimeSpan_compared_to_parameter()
SELECT [b].[Id], [b].[Bool], [b].[Byte], [b].[ByteArray], [b].[DateOnly], [b].[DateTime], [b].[DateTimeOffset], [b].[Decimal], [b].[Double], [b].[Enum], [b].[FlagsEnum], [b].[Float], [b].[Guid], [b].[Int], [b].[Long], [b].[Short], [b].[String], [b].[TimeOnly], [b].[TimeSpan]
FROM [BasicTypesEntities] AS [b]
-WHERE CAST([b].[TimeSpan] AS time) = @time
+WHERE [b].[TimeSpan] = @time
""");
}
@@ -214,7 +214,7 @@ public override async Task Order_by_FromTimeSpan()
"""
SELECT [b].[Id], [b].[Bool], [b].[Byte], [b].[ByteArray], [b].[DateOnly], [b].[DateTime], [b].[DateTimeOffset], [b].[Decimal], [b].[Double], [b].[Enum], [b].[FlagsEnum], [b].[Float], [b].[Guid], [b].[Int], [b].[Long], [b].[Short], [b].[String], [b].[TimeOnly], [b].[TimeSpan]
FROM [BasicTypesEntities] AS [b]
-ORDER BY CAST([b].[TimeSpan] AS time)
+ORDER BY [b].[TimeSpan]
""");
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs
index e63e3b77cdc..5a4194ce066 100644
--- a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs
@@ -1770,7 +1770,7 @@ public override async Task Object_to_string_conversion()
AssertSql(
"""
-SELECT CAST("b"."TestSignedByte" AS TEXT), CAST("b"."TestByte" AS TEXT), CAST("b"."TestInt16" AS TEXT), CAST("b"."TestUnsignedInt16" AS TEXT), CAST("b"."TestInt32" AS TEXT), CAST("b"."TestUnsignedInt32" AS TEXT), CAST("b"."TestInt64" AS TEXT), "b"."TestUnsignedInt64", CAST("b"."TestSingle" AS TEXT), CAST("b"."TestDouble" AS TEXT), CAST("b"."TestDecimal" AS TEXT), CAST("b"."TestCharacter" AS TEXT), CAST("b"."TestDateTime" AS TEXT), CAST("b"."TestDateTimeOffset" AS TEXT), CAST("b"."TestTimeSpan" AS TEXT), CAST("b"."TestDateOnly" AS TEXT), CAST("b"."TestTimeOnly" AS TEXT)
+SELECT CAST("b"."TestSignedByte" AS TEXT), CAST("b"."TestByte" AS TEXT), CAST("b"."TestInt16" AS TEXT), CAST("b"."TestUnsignedInt16" AS TEXT), CAST("b"."TestInt32" AS TEXT), CAST("b"."TestUnsignedInt32" AS TEXT), CAST("b"."TestInt64" AS TEXT), "b"."TestUnsignedInt64", CAST("b"."TestSingle" AS TEXT), CAST("b"."TestDouble" AS TEXT), "b"."TestDecimal", "b"."TestCharacter", "b"."TestDateTime", "b"."TestDateTimeOffset", "b"."TestTimeSpan", "b"."TestDateOnly", "b"."TestTimeOnly"
FROM "BuiltInDataTypes" AS "b"
WHERE "b"."Id" = 13
""");
diff --git a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs
index e33a7ea7fc8..5c9fd84903a 100644
--- a/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs
@@ -1069,7 +1069,7 @@ public override async Task Update_Where_using_navigation_2_set_constant(bool asy
@p='1'
UPDATE "Order Details" AS "o"
-SET "Quantity" = CAST(@p AS INTEGER)
+SET "Quantity" = @p
FROM "Orders" AS "o0"
LEFT JOIN "Customers" AS "c" ON "o0"."CustomerID" = "c"."CustomerID"
WHERE "c"."City" = 'Seattle' AND "o"."OrderID" = "o0"."OrderID"
@@ -1546,7 +1546,7 @@ public override async Task Update_with_PK_pushdown_and_join_and_multiple_setters
@p2='10'
UPDATE "Order Details" AS "o2"
-SET "Quantity" = CAST(@p AS INTEGER),
+SET "Quantity" = @p,
"UnitPrice" = @p2
FROM (
SELECT "o1"."OrderID", "o1"."ProductID"
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs
index 9a71b1de649..c37c20102a8 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs
@@ -62,12 +62,12 @@ SELECT AVG(CAST("p"."NullableLongColumn" AS REAL))
""",
//
"""
-SELECT CAST(AVG("p"."FloatColumn") AS REAL)
+SELECT AVG("p"."FloatColumn")
FROM "Prices" AS "p"
""",
//
"""
-SELECT CAST(AVG("p"."NullableFloatColumn") AS REAL)
+SELECT AVG("p"."NullableFloatColumn")
FROM "Prices" AS "p"
""",
//
@@ -158,6 +158,18 @@ WHEN COALESCE("d"."Foo", 99) = 10 THEN 'A'
END AS "Foo"
FROM "Data" AS "d"
ORDER BY "d"."Id"
+""");
+ }
+
+ public override async Task Like_on_value_converted_string_column_does_not_produce_cast(bool async)
+ {
+ await base.Like_on_value_converted_string_column_does_not_produce_cast(async);
+
+ AssertSql(
+ """
+SELECT "u"."Id", "u"."Name"
+FROM "Users" AS "u"
+WHERE "u"."Name" LIKE 'Name%'
""");
}
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs
index c5651d6ab88..420ca3e1c4f 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs
@@ -2798,7 +2798,7 @@ public override async Task ToString_enum_contains(bool async)
"""
SELECT "m"."CodeName"
FROM "Missions" AS "m"
-WHERE instr(CAST("m"."Difficulty" AS TEXT), 'Med') > 0
+WHERE instr("m"."Difficulty", 'Med') > 0
""");
}
@@ -4413,7 +4413,7 @@ public override async Task Checked_context_with_cast_does_not_fail(bool async)
"""
SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId"
FROM "LocustLeaders" AS "l"
-WHERE CAST("l"."ThreatLevel" AS INTEGER) >= 5
+WHERE "l"."ThreatLevel" >= 5
""");
}
@@ -6514,7 +6514,7 @@ public override async Task Enum_flags_closure_typed_as_different_type_generates_
SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank"
FROM "Gears" AS "g"
-WHERE @prm & CAST("g"."Rank" AS INTEGER) = CAST("g"."Rank" AS INTEGER)
+WHERE @prm & "g"."Rank" = "g"."Rank"
""");
}
@@ -7481,7 +7481,7 @@ public override async Task Checked_context_with_addition_does_not_fail(bool asyn
"""
SELECT "l"."Name", "l"."Discriminator", "l"."LocustHordeId", "l"."ThreatLevel", "l"."ThreatLevelByte", "l"."ThreatLevelNullableByte", "l"."DefeatedByNickname", "l"."DefeatedBySquadId", "l"."HighCommandId"
FROM "LocustLeaders" AS "l"
-WHERE CAST("l"."ThreatLevel" AS INTEGER) <= 5 + CAST("l"."ThreatLevel" AS INTEGER)
+WHERE "l"."ThreatLevel" <= 5 + "l"."ThreatLevel"
""");
}
@@ -8260,7 +8260,7 @@ public override async Task String_concat_on_various_types(bool async)
AssertSql(
"""
-SELECT 'HasSoulPatch ' || CAST("g"."HasSoulPatch" AS TEXT) || ' HasSoulPatch' AS "HasSoulPatch", 'Rank ' || CAST("g"."Rank" AS TEXT) || ' Rank' AS "Rank", 'SquadId ' || CAST("g"."SquadId" AS TEXT) || ' SquadId' AS "SquadId", 'Rating ' || COALESCE(CAST("m"."Rating" AS TEXT), '') || ' Rating' AS "Rating", 'Timeline ' || CAST("m"."Timeline" AS TEXT) || ' Timeline' AS "Timeline"
+SELECT 'HasSoulPatch ' || CAST("g"."HasSoulPatch" AS TEXT) || ' HasSoulPatch' AS "HasSoulPatch", 'Rank ' || CAST("g"."Rank" AS TEXT) || ' Rank' AS "Rank", 'SquadId ' || CAST("g"."SquadId" AS TEXT) || ' SquadId' AS "SquadId", 'Rating ' || COALESCE(CAST("m"."Rating" AS TEXT), '') || ' Rating' AS "Rating", 'Timeline ' || "m"."Timeline" || ' Timeline' AS "Timeline"
FROM "Gears" AS "g"
CROSS JOIN "Missions" AS "m"
ORDER BY "g"."Nickname", "m"."Id"
@@ -8847,7 +8847,7 @@ public override async Task Find_underlying_property_after_GroupJoin_DefaultIfEmp
AssertSql(
"""
-SELECT "g"."FullName", CAST("l0"."ThreatLevel" AS INTEGER) AS "ThreatLevel"
+SELECT "g"."FullName", "l0"."ThreatLevel"
FROM "Gears" AS "g"
LEFT JOIN (
SELECT "l"."ThreatLevel", "l"."DefeatedByNickname"
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs
index 4b96867f894..48a197e21fd 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindSelectQuerySqliteTest.cs
@@ -125,7 +125,7 @@ public override async Task Select_datetime_DayOfWeek_component(bool async)
AssertSql(
"""
-SELECT CAST(CAST(strftime('%w', "o"."OrderDate") AS INTEGER) AS INTEGER)
+SELECT CAST(strftime('%w', "o"."OrderDate") AS INTEGER)
FROM "Orders" AS "o"
""");
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs
index be3c3dab659..3b657bfab60 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs
@@ -426,7 +426,7 @@ public override async Task Inline_collection_with_single_parameter_element_Count
FROM "PrimitiveCollectionsEntity" AS "p"
WHERE (
SELECT COUNT(*)
- FROM (SELECT CAST(@i AS INTEGER) AS "Value") AS "v"
+ FROM (SELECT @i AS "Value") AS "v"
WHERE "v"."Value" > "p"."Id") = 1
""");
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/EnumTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/EnumTranslationsSqliteTest.cs
index a5e62ef3534..8118a3e271f 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/EnumTranslationsSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/EnumTranslationsSqliteTest.cs
@@ -138,13 +138,13 @@ public override async Task Bitwise_and_integral_constant()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE CAST("b"."FlagsEnum" AS INTEGER) & 8 = 8
+WHERE "b"."FlagsEnum" & 8 = 8
""",
//
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE CAST("b"."FlagsEnum" AS INTEGER) & 8 = 8
+WHERE "b"."FlagsEnum" & 8 = 8
""");
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/GuidTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/GuidTranslationsSqliteTest.cs
index b3e125deaa1..0ef654195ee 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/GuidTranslationsSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/GuidTranslationsSqliteTest.cs
@@ -44,7 +44,7 @@ public override async Task ToString_projection()
AssertSql(
"""
-SELECT CAST("b"."Guid" AS TEXT)
+SELECT "b"."Guid"
FROM "BasicTypesEntities" AS "b"
""");
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/MathTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/MathTranslationsSqliteTest.cs
index 7ff0390763c..1c96938b8de 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/MathTranslationsSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/MathTranslationsSqliteTest.cs
@@ -47,7 +47,7 @@ public override async Task Abs_float()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE CAST(abs("b"."Float") AS REAL) = 9.5
+WHERE abs("b"."Float") = 9.5
""");
}
@@ -186,7 +186,7 @@ public override async Task Round_with_digits_float()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE round(CAST("b"."Float" AS REAL), 1) = 255.09999999999999
+WHERE round("b"."Float", 1) = 255.09999999999999
""");
}
@@ -609,7 +609,7 @@ public override async Task Asin_float()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE "b"."Float" >= -1 AND "b"."Float" <= 1 AND CAST(asin("b"."Float") AS REAL) > -1.7976931348623157E+308
+WHERE "b"."Float" >= -1 AND "b"."Float" <= 1 AND asin("b"."Float") > -1.7976931348623157E+308
""");
}
diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Operators/BitwiseOperatorTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Operators/BitwiseOperatorTranslationsSqliteTest.cs
index cac94d3f8e6..8b0426cd3af 100644
--- a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Operators/BitwiseOperatorTranslationsSqliteTest.cs
+++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Operators/BitwiseOperatorTranslationsSqliteTest.cs
@@ -20,11 +20,11 @@ public override async Task Or()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE CAST("b"."Int" AS INTEGER) | "b"."Long" = 7
+WHERE "b"."Int" | "b"."Long" = 7
""",
//
"""
-SELECT CAST("b"."Int" AS INTEGER) | "b"."Long"
+SELECT "b"."Int" | "b"."Long"
FROM "BasicTypesEntities" AS "b"
""");
}
@@ -54,7 +54,7 @@ public override async Task Or_multiple()
"""
SELECT "b"."Id", "b"."Bool", "b"."Byte", "b"."ByteArray", "b"."DateOnly", "b"."DateTime", "b"."DateTimeOffset", "b"."Decimal", "b"."Double", "b"."Enum", "b"."FlagsEnum", "b"."Float", "b"."Guid", "b"."Int", "b"."Long", "b"."Short", "b"."String", "b"."TimeOnly", "b"."TimeSpan"
FROM "BasicTypesEntities" AS "b"
-WHERE CAST("b"."Int" | "b"."Short" AS INTEGER) | "b"."Long" = 7
+WHERE "b"."Int" | "b"."Short" | "b"."Long" = 7
""");
}