diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerTimeOnlyMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerTimeOnlyMethodTranslator.cs index fbc944fcae5..d831f84db16 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerTimeOnlyMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerTimeOnlyMethodTranslator.cs @@ -23,6 +23,12 @@ public class SqlServerTimeOnlyMethodTranslator : IMethodCallTranslator private static readonly MethodInfo IsBetweenMethod = typeof(TimeOnly).GetRuntimeMethod( nameof(TimeOnly.IsBetween), [typeof(TimeOnly), typeof(TimeOnly)])!; + private static readonly MethodInfo FromDateTime = typeof(TimeOnly).GetRuntimeMethod( + nameof(TimeOnly.FromDateTime), [typeof(DateTime)])!; + + private static readonly MethodInfo FromTimeSpan = typeof(TimeOnly).GetRuntimeMethod( + nameof(TimeOnly.FromTimeSpan), [typeof(TimeSpan)])!; + private readonly ISqlExpressionFactory _sqlExpressionFactory; /// @@ -48,7 +54,19 @@ public SqlServerTimeOnlyMethodTranslator(ISqlExpressionFactory sqlExpressionFact IReadOnlyList arguments, IDiagnosticsLogger logger) { - if (method.DeclaringType != typeof(TimeOnly) || instance is null) + if (method.DeclaringType != typeof(TimeOnly)) + { + return null; + } + + if ((method == FromDateTime || method == FromTimeSpan) + && instance is null + && arguments.Count == 1) + { + return _sqlExpressionFactory.Convert(arguments[0], typeof(TimeOnly)); + } + + if (instance is null) { return null; } diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index 493b6b4d3b2..3f5a6adf305 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -7911,6 +7911,83 @@ public virtual Task Where_TimeOnly_subtract_TimeOnly(bool async) async, ss => ss.Set().Where(m => m.Time - new TimeOnly(10, 0, 0) == new TimeSpan(0, 0, 15, 50, 500)).AsTracking()); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + => AssertQuery( + async, + ss => from t in ss.Set() + from m in ss.Set() + where TimeOnly.FromDateTime(t.IssueDate) == m.Time + select new { TagId = t.Id, MissionId = m.Id }, + elementSorter: e => (e.TagId, e.MissionId)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + var time = new TimeOnly(2, 0, 0); + + return AssertQuery( + async, + ss => ss.Set().Where(x => x.Gear != null && TimeOnly.FromDateTime(x.IssueDate.AddHours(x.Gear.SquadId)) == time)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(x => TimeOnly.FromDateTime(x.IssueDate.AddHours(x.Note.Length)) > new TimeOnly(9, 0, 0))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(x => TimeOnly.FromTimeSpan(x.Duration) < x.Time)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + var time = new TimeOnly(1, 2, 3); + + return AssertQuery( + async, + ss => ss.Set().Where(x => TimeOnly.FromTimeSpan(x.Duration) == time)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Order_by_TimeOnly_FromTimeSpan(bool async) + => AssertQuery( + async, + ss => ss.Set().OrderBy(x => TimeOnly.FromTimeSpan(x.Duration)), + assertOrder: true); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + => AssertQuery( + async, + ss => from t in ss.Set() + from m in ss.Set() + where DateOnly.FromDateTime(t.IssueDate) > m.Date + select new { TagId = t.Id, MissionId = m.Id }, + elementSorter: e => (e.TagId, e.MissionId)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + var prm = new DateOnly(2, 10, 11); + + return AssertQuery( + async, + ss => ss.Set().Where(x => new[] { prm, new DateOnly(15, 3, 7) }.Contains(DateOnly.FromDateTime(x.IssueDate)))); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Basic_query_gears(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index 44213bb55c5..11677a5fade 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -9260,6 +9260,111 @@ public override async Task Where_TimeOnly_subtract_TimeOnly(bool async) AssertSql(); } + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] AS [t] +CROSS JOIN [Missions] AS [m] +WHERE CAST([t].[IssueDate] AS time) = [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='02:00' (DbType = Time) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +LEFT JOIN [Gears] AS [g] ON [t].[GearNickName] = [g].[Nickname] AND [t].[GearSquadId] = [g].[SquadId] +WHERE [g].[Nickname] IS NOT NULL AND [g].[SquadId] IS NOT NULL AND CAST(DATEADD(hour, CAST(CAST([g].[SquadId] AS float) AS int), [t].[IssueDate]) AS time) = @__time_0 +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); + + AssertSql( +""" +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CAST([m].[Duration] AS time) < [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='01:02' (DbType = Time) + +SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CAST([m].[Duration] AS time) = @__time_0 +"""); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + await base.Order_by_TimeOnly_FromTimeSpan(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +ORDER BY CAST([m].[Duration] AS time) +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] AS [t] +CROSS JOIN [Missions] AS [m] +WHERE CAST([t].[IssueDate] AS date) > [m].[Date] +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); + + AssertSql( +""" +@__prm_0='10/11/0002' (DbType = Date) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +WHERE CAST([t].[IssueDate] AS date) IN (@__prm_0, '0015-03-07') +"""); + } + public override async Task Include_on_entity_that_is_not_present_in_final_projection_but_uses_TypeIs_instead(bool async) { await base.Include_on_entity_that_is_not_present_in_final_projection_but_uses_TypeIs_instead(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 8b412b4f9be..737819a1b91 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -11861,6 +11861,117 @@ public override async Task Where_TimeOnly_subtract_TimeOnly(bool async) AssertSql(); } + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] AS [t] +CROSS JOIN [Missions] AS [m] +WHERE CAST([t].[IssueDate] AS time) = [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='02:00' (DbType = Time) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +LEFT JOIN ( + SELECT [g].[Nickname], [g].[SquadId] + FROM [Gears] AS [g] + UNION ALL + SELECT [o].[Nickname], [o].[SquadId] + FROM [Officers] AS [o] +) AS [u] ON [t].[GearNickName] = [u].[Nickname] AND [t].[GearSquadId] = [u].[SquadId] +WHERE [u].[Nickname] IS NOT NULL AND [u].[SquadId] IS NOT NULL AND CAST(DATEADD(hour, CAST(CAST([u].[SquadId] AS float) AS int), [t].[IssueDate]) AS time) = @__time_0 +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); + + AssertSql( +""" +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CAST([m].[Duration] AS time) < [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='01:02' (DbType = Time) + +SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CAST([m].[Duration] AS time) = @__time_0 +"""); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + await base.Order_by_TimeOnly_FromTimeSpan(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +ORDER BY CAST([m].[Duration] AS time) +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] AS [t] +CROSS JOIN [Missions] AS [m] +WHERE CAST([t].[IssueDate] AS date) > [m].[Date] +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); + + AssertSql( +""" +@__prm_0='10/11/0002' (DbType = Date) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +WHERE CAST([t].[IssueDate] AS date) IN (@__prm_0, '0015-03-07') +"""); + } + public override async Task Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(bool async) { await base.Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index 2ef5e6d9969..33b337791d1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -10088,6 +10088,114 @@ public override async Task Where_TimeOnly_subtract_TimeOnly(bool async) AssertSql(); } + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] AS [t] +CROSS JOIN [Missions] AS [m] +WHERE CAST([t].[IssueDate] AS time) = [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='02:00' (DbType = Time) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +LEFT JOIN ( + SELECT [g].[Nickname], [g].[SquadId] + FROM [Gears] AS [g] +) AS [s] ON [t].[GearNickName] = [s].[Nickname] AND [t].[GearSquadId] = [s].[SquadId] +WHERE [s].[Nickname] IS NOT NULL AND [s].[SquadId] IS NOT NULL AND CAST(DATEADD(hour, CAST(CAST([s].[SquadId] AS float) AS int), [t].[IssueDate]) AS time) = @__time_0 +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); + + AssertSql( +""" +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CAST([m].[Duration] AS time) < [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='01:02' (DbType = Time) + +SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CAST([m].[Duration] AS time) = @__time_0 +"""); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + await base.Order_by_TimeOnly_FromTimeSpan(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[CodeName], [m].[Date], [m].[Duration], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] AS [m] +ORDER BY CAST([m].[Duration] AS time) +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] AS [t] +CROSS JOIN [Missions] AS [m] +WHERE CAST([t].[IssueDate] AS date) > [m].[Date] +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); + + AssertSql( +""" +@__prm_0='10/11/0002' (DbType = Date) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note] +FROM [Tags] AS [t] +WHERE CAST([t].[IssueDate] AS date) IN (@__prm_0, '0015-03-07') +"""); + } + public override async Task Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(bool async) { await base.Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index c4dc97dd52a..ac6fedba78c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -431,6 +431,111 @@ public override async Task Where_TimeOnly_subtract_TimeOnly(bool async) AssertSql(); } + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] +CROSS JOIN [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] +WHERE CAST([t].[IssueDate] AS time) = [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='02:00' (DbType = Time) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], [t].[PeriodEnd], [t].[PeriodStart] +FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] +LEFT JOIN [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] ON [t].[GearNickName] = [g].[Nickname] AND [t].[GearSquadId] = [g].[SquadId] +WHERE [g].[Nickname] IS NOT NULL AND [g].[SquadId] IS NOT NULL AND CAST(DATEADD(hour, CAST(CAST([g].[SquadId] AS float) AS int), [t].[IssueDate]) AS time) = @__time_0 +"""); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + await base.Where_TimeOnly_FromDateTime_compared_to_constant(async); + + AssertSql( +""" +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], [t].[PeriodEnd], [t].[PeriodStart] +FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] +WHERE CAST(DATEADD(hour, CAST(CAST(CAST(LEN([t].[Note]) AS int) AS float) AS int), [t].[IssueDate]) AS time) > '09:00:00' +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_property(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[PeriodEnd], [m].[PeriodStart], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] +WHERE CAST([m].[Duration] AS time) < [m].[Time] +"""); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + await base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async); + + AssertSql( +""" +@__time_0='01:02' (DbType = Time) + +SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[PeriodEnd], [m].[PeriodStart], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] +WHERE CAST([m].[Duration] AS time) = @__time_0 +"""); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + await base.Order_by_TimeOnly_FromTimeSpan(async); + + AssertSql( +""" +SELECT [m].[Id], [m].[BriefingDocument], [m].[BriefingDocumentFileExtension], [m].[CodeName], [m].[Date], [m].[Duration], [m].[PeriodEnd], [m].[PeriodStart], [m].[Rating], [m].[Time], [m].[Timeline] +FROM [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] +ORDER BY CAST([m].[Duration] AS time) +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_property(async); + + AssertSql( +""" +SELECT [t].[Id] AS [TagId], [m].[Id] AS [MissionId] +FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] +CROSS JOIN [Missions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [m] +WHERE CAST([t].[IssueDate] AS date) > [m].[Date] +"""); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + await base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async); + + AssertSql( +""" +@__prm_0='10/11/0002' (DbType = Date) + +SELECT [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], [t].[PeriodEnd], [t].[PeriodStart] +FROM [Tags] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [t] +WHERE CAST([t].[IssueDate] AS date) IN (@__prm_0, '0015-03-07') +"""); + } + public override async Task Basic_query_gears(bool async) { await base.Basic_query_gears(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 155d9365ecc..f3cf89b8396 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -698,6 +698,70 @@ public override async Task Where_TimeOnly_subtract_TimeOnly(bool async) AssertSql(); } + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_constant(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromTimeSpan_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Order_by_TimeOnly_FromTimeSpan(async)); + + AssertSql(); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_DateOnly_FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async)); + + AssertSql(); + } + public override async Task Optional_navigation_type_compensation_works_with_DTOs(bool async) { await base.Optional_navigation_type_compensation_works_with_DTOs(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs index 8cf55d0a7d5..f143042a645 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPCGearsOfWarQuerySqliteTest.cs @@ -361,6 +361,70 @@ public override Task Where_TimeOnly_subtract_TimeOnly(bool async) // TimeSpan. Issue #18844. => AssertTranslationFailed(() => base.Where_TimeOnly_subtract_TimeOnly(async)); + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_constant(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromTimeSpan_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Order_by_TimeOnly_FromTimeSpan(async)); + + AssertSql(); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_DateOnly_FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async)); + + AssertSql(); + } + public override async Task Where_subquery_with_ElementAt_using_column_as_index(bool async) { var message = (await Assert.ThrowsAsync( diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs index ebfe74bfc82..d0e9d1fb3fa 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/TPTGearsOfWarQuerySqliteTest.cs @@ -361,6 +361,70 @@ public override Task Where_TimeOnly_subtract_TimeOnly(bool async) // TimeSpan. Issue #18844. => AssertTranslationFailed(() => base.Where_TimeOnly_subtract_TimeOnly(async)); + public override async Task Where_TimeOnly_FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromDateTime_compared_to_constant(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromDateTime_compared_to_constant(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromTimeSpan_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_TimeOnly_FromTimeSpan_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_TimeOnly_FromTimeSpan_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Order_by_TimeOnly_FromTimeSpan(async)); + + AssertSql(); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_DateOnly_FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Where_DateOnly_FromDateTime_compared_to_constant_and_parameter(async)); + + AssertSql(); + } + public override async Task Where_subquery_with_ElementAt_using_column_as_index(bool async) { var message = (await Assert.ThrowsAsync(