diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsCosmosTest.cs new file mode 100644 index 00000000000..177177b7990 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsCosmosTest.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateOnlyTranslationsCosmosTest : DateOnlyTranslationsTestBase +{ + public DateOnlyTranslationsCosmosTest(BasicTypesQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override Task Year(bool async) + => AssertTranslationFailed(() => base.Year(async)); + + public override Task Month(bool async) + => AssertTranslationFailed(() => base.Month(async)); + + public override Task Day(bool async) + => AssertTranslationFailed(() => base.Day(async)); + + public override Task DayOfYear(bool async) + => AssertTranslationFailed(() => base.DayOfYear(async)); + + public override Task DayOfWeek(bool async) + => AssertTranslationFailed(() => base.DayOfWeek(async)); + + public override Task AddYears(bool async) + => AssertTranslationFailed(() => base.AddYears(async)); + + public override Task AddMonths(bool async) + => AssertTranslationFailed(() => base.AddMonths(async)); + + public override Task AddDays(bool async) + => AssertTranslationFailed(() => base.AddDays(async)); + + public override Task FromDateTime(bool async) + => AssertTranslationFailed(() => base.FromDateTime(async)); + + public override Task FromDateTime_compared_to_property(bool async) + => AssertTranslationFailed(() => base.FromDateTime(async)); + + public override Task FromDateTime_compared_to_constant_and_parameter(bool async) + => AssertTranslationFailed(() => base.FromDateTime(async)); + + public override Task ToDateTime_property_with_constant_TimeOnly(bool async) + => AssertTranslationFailed(() => base.ToDateTime_property_with_constant_TimeOnly(async)); + + public override Task ToDateTime_property_with_property_TimeOnly(bool async) + => AssertTranslationFailed(() => base.ToDateTime_property_with_property_TimeOnly(async)); + + public override Task ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) + => AssertTranslationFailed(() => base.ToDateTime_constant_DateTime_with_property_TimeOnly(async)); + + public override Task ToDateTime_with_complex_DateTime(bool async) + => AssertTranslationFailed(() => base.ToDateTime_with_complex_DateTime(async)); + + public override Task ToDateTime_with_complex_TimeOnly(bool async) + => AssertTranslationFailed(() => base.ToDateTime_with_complex_TimeOnly(async)); + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsCosmosTest.cs new file mode 100644 index 00000000000..6f087471e65 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsCosmosTest.cs @@ -0,0 +1,423 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit.Sdk; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateTimeOffsetTranslationsCosmosTest : DateTimeOffsetTranslationsTestBase +{ + public DateTimeOffsetTranslationsCosmosTest(BasicTypesQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Now(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.Now(async)); + + AssertSql(); + } + + public override Task UtcNow(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.UtcNow(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["DateTimeOffset"] != GetCurrentDateTime()) +"""); + }); + + public override async Task Date(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.Date(async)); + + AssertSql(); + } + + public override async Task Year(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Year(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("yyyy", c["DateTimeOffset"]) = 1998) +"""); + }); + } + } + + public override async Task Month(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Month(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("mm", c["DateTimeOffset"]) = 5) +"""); + }); + } + } + + public override async Task DayOfYear(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.DayOfYear(async)); + + AssertSql(); + } + + public override async Task Day(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Day(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("dd", c["DateTimeOffset"]) = 4) +"""); + }); + } + } + + public override async Task Hour(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Hour(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("hh", c["DateTimeOffset"]) = 15) +"""); + }); + } + } + + public override async Task Minute(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Minute(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("mi", c["DateTimeOffset"]) = 30) +"""); + }); + } + } + + public override async Task Second(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Second(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("ss", c["DateTimeOffset"]) = 10) +"""); + }); + } + } + + + public override async Task Millisecond(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Millisecond(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("ms", c["DateTimeOffset"]) = 123) +"""); + }); + } + } + + public override async Task Microsecond(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Microsecond(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE ((DateTimePart("mcs", c["DateTimeOffset"]) % 1000) = 456) +"""); + }); + } + } + + public override async Task Nanosecond(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.Nanosecond(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE ((DateTimePart("ns", c["DateTimeOffset"]) % 1000) = 400) +"""); + }); + } + } + + public override Task TimeOfDay(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.TimeOfDay(a); + + AssertSql( + """ +SELECT VALUE c["DateTimeOffset"] +FROM root c +"""); + }); + + public override async Task AddYears(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddYears(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("yyyy", 1, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override async Task AddMonths(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddMonths(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("mm", 1, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override async Task AddDays(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddSeconds(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("ss", 1.0, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override async Task AddHours(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddHours(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("hh", 1.0, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override async Task AddMinutes(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddMinutes(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("mi", 1.0, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override async Task AddSeconds(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddSeconds(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("ss", 1.0, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override async Task AddMilliseconds(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 + await Assert.ThrowsAsync(() => base.AddMilliseconds(a)); + + AssertSql( + """ +SELECT VALUE DateTimeAdd("ms", 300.0, c["DateTimeOffset"]) +FROM root c +"""); + }); + } + } + + public override Task ToUnixTimeMilliseconds(bool async) + => AssertTranslationFailed(() => base.ToUnixTimeMilliseconds(async)); + + public override Task ToUnixTimeSecond(bool async) + => AssertTranslationFailed(() => base.ToUnixTimeSecond(async)); + + public override Task Milliseconds_parameter_and_constant(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Milliseconds_parameter_and_constant(a); + + AssertSql( + """ +SELECT VALUE COUNT(1) +FROM root c +WHERE (c["DateTimeOffset"] = "1902-01-02T10:00:00.1234567+01:30") +"""); + }); + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsCosmosTest.cs new file mode 100644 index 00000000000..f000eca2ada --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsCosmosTest.cs @@ -0,0 +1,256 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateTimeTranslationsCosmosTest : DateTimeTranslationsTestBase +{ + public DateTimeTranslationsCosmosTest(BasicTypesQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Now(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.Now(async)); + + AssertSql(); + } + + public override Task UtcNow(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.UtcNow(a); + + AssertSql( + """ +@myDatetime=? + +SELECT VALUE c +FROM root c +WHERE (GetCurrentDateTime() != @myDatetime) +"""); + }); + + public override async Task Today(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.Today(async)); + + AssertSql(); + } + + public override async Task Date(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.Date(async)); + + AssertSql(); + } + + public override Task AddYear(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.AddYear(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("yyyy", DateTimeAdd("yyyy", 1, c["DateTime"])) = 1999) +"""); + }); + + public override Task Year(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Year(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("yyyy", c["DateTime"]) = 1998) +"""); + }); + + public override Task Month(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Month(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("mm", c["DateTime"]) = 5) +"""); + }); + + public override async Task DayOfYear(bool async) + { + // DateTime.DayOfYear not supported by Cosmos + await AssertTranslationFailed(() => base.DayOfYear(async)); + + AssertSql(); + } + + public override Task Day(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Day(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("dd", c["DateTime"]) = 4) +"""); + }); + + public override Task Hour(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Hour(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("hh", c["DateTime"]) = 15) +"""); + }); + + public override Task Minute(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Minute(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("mi", c["DateTime"]) = 30) +"""); + }); + + public override Task Second(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Second(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("ss", c["DateTime"]) = 10) +"""); + }); + + public override Task Millisecond(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Millisecond(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (DateTimePart("ms", c["DateTime"]) = 123) +"""); + }); + + public override async Task TimeOfDay(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.TimeOfDay(async)); + + AssertSql(); + } + + public override async Task subtract_and_TotalDays(bool async) + { + // Cosmos client evaluation. Issue #17246. + await AssertTranslationFailed(() => base.subtract_and_TotalDays(async)); + + AssertSql(); + } + + public override Task Parse_with_constant(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Parse_with_constant(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["DateTime"] = "1998-05-04T15:30:10") +"""); + }); + + public override Task Parse_with_parameter(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.Parse_with_parameter(a); + + AssertSql( + """ +@Parse=? + +SELECT VALUE c +FROM root c +WHERE (c["DateTime"] = @Parse) +"""); + }); + + public override Task New_with_constant(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.New_with_constant(a); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE (c["DateTime"] = "1998-05-04T15:30:10") +"""); + }); + + public override Task New_with_parameters(bool async) + => Fixture.NoSyncTest( + async, async a => + { + await base.New_with_parameters(a); + + AssertSql( + """ +@p=? + +SELECT VALUE c +FROM root c +WHERE (c["DateTime"] = @p) +"""); + }); + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsCosmosTest.cs new file mode 100644 index 00000000000..5c797025083 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsCosmosTest.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit.Sdk; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class TimeOnlyTranslationsCosmosTest : TimeOnlyTranslationsTestBase +{ + public TimeOnlyTranslationsCosmosTest(BasicTypesQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override Task Hour(bool async) + => AssertTranslationFailed(() => base.Hour(async)); + + public override Task Minute(bool async) + => AssertTranslationFailed(() => base.Minute(async)); + + public override Task Second(bool async) + => AssertTranslationFailed(() => base.Second(async)); + + public override Task Millisecond(bool async) + => AssertTranslationFailed(() => base.Millisecond(async)); + + public override Task Microsecond(bool async) + => AssertTranslationFailed(() => base.Microsecond(async)); + + public override Task Nanosecond(bool async) + => AssertTranslationFailed(() => base.Nanosecond(async)); + + public override Task AddHours(bool async) + => AssertTranslationFailed(() => base.AddHours(async)); + + public override Task AddMinutes(bool async) + => AssertTranslationFailed(() => base.AddMinutes(async)); + + public override Task Add_TimeSpan(bool async) + => AssertTranslationFailed(() => base.Add_TimeSpan(async)); + + public override Task IsBetween(bool async) + => AssertTranslationFailed(() => base.IsBetween(async)); + + public override async Task Subtract(bool async) + { + // Always throws for sync. + if (async) + { + await Fixture.NoSyncTest( + async, async a => + { + // See #35311 + await Assert.ThrowsAsync(() => base.Subtract(a)); + + AssertSql( + """ +SELECT VALUE c +FROM root c +WHERE ((c["TimeOnly"] - "03:00:00") = "12:30:10") +"""); + }); + } + } + + public override Task FromDateTime_compared_to_property(bool async) + => AssertTranslationFailed(() => base.FromDateTime_compared_to_property(async)); + + public override Task FromDateTime_compared_to_parameter(bool async) + => AssertTranslationFailed(() => base.FromDateTime_compared_to_parameter(async)); + + public override Task FromDateTime_compared_to_constant(bool async) + => AssertTranslationFailed(() => base.FromDateTime_compared_to_constant(async)); + + public override Task FromTimeSpan_compared_to_property(bool async) + => AssertTranslationFailed(() => base.FromTimeSpan_compared_to_property(async)); + + public override Task FromTimeSpan_compared_to_parameter(bool async) + => AssertTranslationFailed(() => base.FromTimeSpan_compared_to_parameter(async)); + + public override Task Order_by_FromTimeSpan(bool async) + => AssertTranslationFailed(() => base.Order_by_FromTimeSpan(async)); + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsCosmosTest.cs new file mode 100644 index 00000000000..c699dd26c29 --- /dev/null +++ b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsCosmosTest.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class TimeSpanTranslationsCosmosTest : TimeSpanTranslationsTestBase +{ + public TimeSpanTranslationsCosmosTest(BasicTypesQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override Task Hours(bool async) + => AssertTranslationFailed(() => base.Hours(async)); + + public override Task Minutes(bool async) + => AssertTranslationFailed(() => base.Minutes(async)); + + public override Task Seconds(bool async) + => AssertTranslationFailed(() => base.Seconds(async)); + + public override Task Milliseconds(bool async) + => AssertTranslationFailed(() => base.Milliseconds(async)); + + public override Task Microseconds(bool async) + => AssertTranslationFailed(() => base.Microseconds(async)); + + public override Task Nanoseconds(bool async) + => AssertTranslationFailed(() => base.Nanoseconds(async)); + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/TemporalTranslationsCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/Translations/TemporalTranslationsCosmosTest.cs deleted file mode 100644 index 721a5c2a43b..00000000000 --- a/test/EFCore.Cosmos.FunctionalTests/Query/Translations/TemporalTranslationsCosmosTest.cs +++ /dev/null @@ -1,814 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit.Sdk; - -namespace Microsoft.EntityFrameworkCore.Query.Translations; - -public class TemporalTranslationsCosmosTest : TemporalTranslationsTestBase -{ - public TemporalTranslationsCosmosTest(BasicTypesQueryCosmosFixture fixture, ITestOutputHelper testOutputHelper) : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } - - #region DateTime - - public override async Task DateTime_Now(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTime_Now(async)); - - AssertSql(); - } - - public override Task DateTime_UtcNow(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_UtcNow(a); - - AssertSql( - """ -@myDatetime=? - -SELECT VALUE c -FROM root c -WHERE (GetCurrentDateTime() != @myDatetime) -"""); - }); - - public override async Task DateTime_Today(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTime_Today(async)); - - AssertSql(); - } - - public override async Task DateTime_Date(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTime_Date(async)); - - AssertSql(); - } - - public override Task DateTime_AddYear(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_AddYear(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("yyyy", DateTimeAdd("yyyy", 1, c["DateTime"])) = 1999) -"""); - }); - - public override Task DateTime_Year(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Year(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("yyyy", c["DateTime"]) = 1998) -"""); - }); - - public override Task DateTime_Month(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Month(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("mm", c["DateTime"]) = 5) -"""); - }); - - public override async Task DateTime_DayOfYear(bool async) - { - // DateTime.DayOfYear not supported by Cosmos - await AssertTranslationFailed(() => base.DateTime_DayOfYear(async)); - - AssertSql(); - } - - public override Task DateTime_Day(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Day(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("dd", c["DateTime"]) = 4) -"""); - }); - - public override Task DateTime_Hour(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Hour(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("hh", c["DateTime"]) = 15) -"""); - }); - - public override Task DateTime_Minute(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Minute(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("mi", c["DateTime"]) = 30) -"""); - }); - - public override Task DateTime_Second(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Second(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("ss", c["DateTime"]) = 10) -"""); - }); - - public override Task DateTime_Millisecond(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Millisecond(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("ms", c["DateTime"]) = 123) -"""); - }); - - public override async Task DateTime_TimeOfDay(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTime_TimeOfDay(async)); - - AssertSql(); - } - - public override async Task DateTime_subtract_and_TotalDays(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTime_subtract_and_TotalDays(async)); - - AssertSql(); - } - - public override Task DateTime_Parse_with_constant(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Parse_with_constant(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (c["DateTime"] = "1998-05-04T15:30:10") -"""); - }); - - public override Task DateTime_Parse_with_parameter(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_Parse_with_parameter(a); - - AssertSql( - """ -@Parse=? - -SELECT VALUE c -FROM root c -WHERE (c["DateTime"] = @Parse) -"""); - }); - - public override Task DateTime_new_with_constant(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_new_with_constant(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (c["DateTime"] = "1998-05-04T15:30:10") -"""); - }); - - public override Task DateTime_new_with_parameters(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTime_new_with_parameters(a); - - AssertSql( - """ -@p=? - -SELECT VALUE c -FROM root c -WHERE (c["DateTime"] = @p) -"""); - }); - - #endregion DateTime - - #region DateOnly - - public override Task DateOnly_Year(bool async) - => AssertTranslationFailed(() => base.DateOnly_Year(async)); - - public override Task DateOnly_Month(bool async) - => AssertTranslationFailed(() => base.DateOnly_Month(async)); - - public override Task DateOnly_Day(bool async) - => AssertTranslationFailed(() => base.DateOnly_Day(async)); - - public override Task DateOnly_DayOfYear(bool async) - => AssertTranslationFailed(() => base.DateOnly_DayOfYear(async)); - - public override Task DateOnly_DayOfWeek(bool async) - => AssertTranslationFailed(() => base.DateOnly_DayOfWeek(async)); - - public override Task DateOnly_AddYears(bool async) - => AssertTranslationFailed(() => base.DateOnly_AddYears(async)); - - public override Task DateOnly_AddMonths(bool async) - => AssertTranslationFailed(() => base.DateOnly_AddMonths(async)); - - public override Task DateOnly_AddDays(bool async) - => AssertTranslationFailed(() => base.DateOnly_AddDays(async)); - - public override Task DateOnly_FromDateTime(bool async) - => AssertTranslationFailed(() => base.DateOnly_FromDateTime(async)); - - public override Task DateOnly_FromDateTime_compared_to_property(bool async) - => AssertTranslationFailed(() => base.DateOnly_FromDateTime(async)); - - public override Task DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) - => AssertTranslationFailed(() => base.DateOnly_FromDateTime(async)); - - public override Task DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(bool async) - => AssertTranslationFailed(() => base.DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(async)); - - public override Task DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(bool async) - => AssertTranslationFailed(() => base.DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(async)); - - public override Task DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) - => AssertTranslationFailed(() => base.DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(async)); - - public override Task DateOnly_ToDateTime_with_complex_DateTime(bool async) - => AssertTranslationFailed(() => base.DateOnly_ToDateTime_with_complex_DateTime(async)); - - public override Task DateOnly_ToDateTime_with_complex_TimeOnly(bool async) - => AssertTranslationFailed(() => base.DateOnly_ToDateTime_with_complex_TimeOnly(async)); - - #endregion DateOnly - - #region TimeOnly - - public override Task TimeOnly_Hour(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Hour(async)); - - public override Task TimeOnly_Minute(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Minute(async)); - - public override Task TimeOnly_Second(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Second(async)); - - public override Task TimeOnly_Millisecond(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Millisecond(async)); - - public override Task TimeOnly_Microsecond(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Microsecond(async)); - - public override Task TimeOnly_Nanosecond(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Nanosecond(async)); - - public override Task TimeOnly_AddHours(bool async) - => AssertTranslationFailed(() => base.TimeOnly_AddHours(async)); - - public override Task TimeOnly_AddMinutes(bool async) - => AssertTranslationFailed(() => base.TimeOnly_AddMinutes(async)); - - public override Task TimeOnly_Add_TimeSpan(bool async) - => AssertTranslationFailed(() => base.TimeOnly_Add_TimeSpan(async)); - - public override Task TimeOnly_IsBetween(bool async) - => AssertTranslationFailed(() => base.TimeOnly_IsBetween(async)); - - public override async Task TimeOnly_subtract_TimeOnly(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // See #35311 - await Assert.ThrowsAsync(() => base.TimeOnly_subtract_TimeOnly(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE ((c["TimeOnly"] - "03:00:00") = "12:30:10") -"""); - }); - } - } - - public override Task TimeOnly_FromDateTime_compared_to_property(bool async) - => AssertTranslationFailed(() => base.TimeOnly_FromDateTime_compared_to_property(async)); - - public override Task TimeOnly_FromDateTime_compared_to_parameter(bool async) - => AssertTranslationFailed(() => base.TimeOnly_FromDateTime_compared_to_parameter(async)); - - public override Task TimeOnly_FromDateTime_compared_to_constant(bool async) - => AssertTranslationFailed(() => base.TimeOnly_FromDateTime_compared_to_constant(async)); - - public override Task TimeOnly_FromTimeSpan_compared_to_property(bool async) - => AssertTranslationFailed(() => base.TimeOnly_FromTimeSpan_compared_to_property(async)); - - public override Task TimeOnly_FromTimeSpan_compared_to_parameter(bool async) - => AssertTranslationFailed(() => base.TimeOnly_FromTimeSpan_compared_to_parameter(async)); - - public override Task Order_by_TimeOnly_FromTimeSpan(bool async) - => AssertTranslationFailed(() => base.Order_by_TimeOnly_FromTimeSpan(async)); - - #endregion TimeOnly - - #region DateTimeOffset - - public override async Task DateTimeOffset_Now(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTimeOffset_Now(async)); - - AssertSql(); - } - - public override Task DateTimeOffset_UtcNow(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTimeOffset_UtcNow(a); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (c["DateTimeOffset"] != GetCurrentDateTime()) -"""); - }); - - public override async Task DateTimeOffset_Date(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTimeOffset_Date(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Year(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Year(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("yyyy", c["DateTimeOffset"]) = 1998) -"""); - }); - } - } - - public override async Task DateTimeOffset_Month(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Month(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("mm", c["DateTimeOffset"]) = 5) -"""); - }); - } - } - - public override async Task DateTimeOffset_DayOfYear(bool async) - { - // Cosmos client evaluation. Issue #17246. - await AssertTranslationFailed(() => base.DateTimeOffset_DayOfYear(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Day(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Day(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("dd", c["DateTimeOffset"]) = 4) -"""); - }); - } - } - - public override async Task DateTimeOffset_Hour(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Hour(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("hh", c["DateTimeOffset"]) = 15) -"""); - }); - } - } - - public override async Task DateTimeOffset_Minute(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Minute(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("mi", c["DateTimeOffset"]) = 30) -"""); - }); - } - } - - public override async Task DateTimeOffset_Second(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Second(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("ss", c["DateTimeOffset"]) = 10) -"""); - }); - } - } - - - public override async Task DateTimeOffset_Millisecond(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Millisecond(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE (DateTimePart("ms", c["DateTimeOffset"]) = 123) -"""); - }); - } - } - - public override async Task DateTimeOffset_Microsecond(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Microsecond(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE ((DateTimePart("mcs", c["DateTimeOffset"]) % 1000) = 456) -"""); - }); - } - } - - public override async Task DateTimeOffset_Nanosecond(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_Nanosecond(a)); - - AssertSql( - """ -SELECT VALUE c -FROM root c -WHERE ((DateTimePart("ns", c["DateTimeOffset"]) % 1000) = 400) -"""); - }); - } - } - - public override Task DateTimeOffset_TimeOfDay(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTimeOffset_TimeOfDay(a); - - AssertSql( - """ -SELECT VALUE c["DateTimeOffset"] -FROM root c -"""); - }); - - public override async Task DateTimeOffset_AddYears(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddYears(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("yyyy", 1, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override async Task DateTimeOffset_AddMonths(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddMonths(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("mm", 1, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override async Task DateTimeOffset_AddDays(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddSeconds(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("ss", 1.0, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override async Task DateTimeOffset_AddHours(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddHours(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("hh", 1.0, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override async Task DateTimeOffset_AddMinutes(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddMinutes(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("mi", 1.0, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override async Task DateTimeOffset_AddSeconds(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddSeconds(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("ss", 1.0, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override async Task DateTimeOffset_AddMilliseconds(bool async) - { - // Always throws for sync. - if (async) - { - await Fixture.NoSyncTest( - async, async a => - { - // Our persisted representation of DateTimeOffset (xxx+00:00) isn't supported by Cosmos (should be xxxZ). #35310 - await Assert.ThrowsAsync(() => base.DateTimeOffset_AddMilliseconds(a)); - - AssertSql( - """ -SELECT VALUE DateTimeAdd("ms", 300.0, c["DateTimeOffset"]) -FROM root c -"""); - }); - } - } - - public override Task DateTimeOffset_ToUnixTimeMilliseconds(bool async) - => AssertTranslationFailed(() => base.DateTimeOffset_ToUnixTimeMilliseconds(async)); - - public override Task DateTimeOffset_ToUnixTimeSecond(bool async) - => AssertTranslationFailed(() => base.DateTimeOffset_ToUnixTimeSecond(async)); - - public override Task DateTimeOffset_milliseconds_parameter_and_constant(bool async) - => Fixture.NoSyncTest( - async, async a => - { - await base.DateTimeOffset_milliseconds_parameter_and_constant(a); - - AssertSql( - """ -SELECT VALUE COUNT(1) -FROM root c -WHERE (c["DateTimeOffset"] = "1902-01-02T10:00:00.1234567+01:30") -"""); - }); - - #endregion DateTimeOffset - - #region TimeSpan - - public override Task TimeSpan_Hours(bool async) - => AssertTranslationFailed(() => base.TimeSpan_Hours(async)); - - public override Task TimeSpan_Minutes(bool async) - => AssertTranslationFailed(() => base.TimeSpan_Minutes(async)); - - public override Task TimeSpan_Seconds(bool async) - => AssertTranslationFailed(() => base.TimeSpan_Seconds(async)); - - public override Task TimeSpan_Milliseconds(bool async) - => AssertTranslationFailed(() => base.TimeSpan_Milliseconds(async)); - - public override Task TimeSpan_Microseconds(bool async) - => AssertTranslationFailed(() => base.TimeSpan_Microseconds(async)); - - public override Task TimeSpan_Nanoseconds(bool async) - => AssertTranslationFailed(() => base.TimeSpan_Nanoseconds(async)); - - #endregion TimeSpan - - [ConditionalFact] - public virtual void Check_all_tests_overridden() - => TestHelpers.AssertAllMethodsOverridden(GetType()); - - private void AssertSql(params string[] expected) - => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); -} diff --git a/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateOnlyTranslationsTestBase.cs b/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateOnlyTranslationsTestBase.cs new file mode 100644 index 00000000000..e34dd951442 --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateOnlyTranslationsTestBase.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public abstract class DateOnlyTranslationsTestBase(TFixture fixture) : QueryTestBase(fixture) + where TFixture : BasicTypesQueryFixtureBase, new() +{ + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Year(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.Year == 1990)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Month(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.Month == 11)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Day(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.Day == 10)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task DayOfYear(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.DayOfYear == 314)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task DayOfWeek(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.DayOfWeek == System.DayOfWeek.Saturday)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddYears(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.AddYears(3) == new DateOnly(1993, 11, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddMonths(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.AddMonths(3) == new DateOnly(1991, 2, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddDays(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateOnly.AddDays(3) == new DateOnly(1990, 11, 13))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromDateTime(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => DateOnly.FromDateTime(o.DateTime) == new DateOnly(1998, 5, 4))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromDateTime_compared_to_property(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => DateOnly.FromDateTime(o.DateTime) == o.DateOnly)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromDateTime_compared_to_constant_and_parameter(bool async) + { + var dateOnly = new DateOnly(2, 10, 11); + + return AssertQuery( + async, + ss => ss.Set() + .Where(x => new[] { dateOnly, new DateOnly(1998, 5, 4) }.Contains(DateOnly.FromDateTime(x.DateTime)))); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToDateTime_property_with_constant_TimeOnly(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(o => o.DateOnly.ToDateTime(new TimeOnly(21, 5, 19, 940, 500)) == new DateTime(2020, 1, 1, 21, 5, 19, 940, 500))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToDateTime_property_with_property_TimeOnly(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(o => o.DateOnly.ToDateTime(o.TimeOnly) == new DateTime(2020, 1, 1, 15, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(o => new DateOnly(1990, 11, 10).ToDateTime(o.TimeOnly) == new DateTime(1990, 11, 10, 15, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToDateTime_with_complex_DateTime(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(o => o.DateOnly.AddYears(1).ToDateTime(o.TimeOnly) == new DateTime(2021, 1, 1, 15, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToDateTime_with_complex_TimeOnly(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(o => o.DateOnly.ToDateTime(o.TimeOnly.AddHours(1)) == new DateTime(2020, 1, 1, 16, 30, 10)) + .AsTracking()); +} diff --git a/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateTimeOffsetTranslationsTestBase.cs b/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateTimeOffsetTranslationsTestBase.cs new file mode 100644 index 00000000000..de1a854e07c --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateTimeOffsetTranslationsTestBase.cs @@ -0,0 +1,201 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public abstract class DateTimeOffsetTranslationsTestBase(TFixture fixture) : QueryTestBase(fixture) + where TFixture : BasicTypesQueryFixtureBase, new() +{ + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Now(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset != DateTimeOffset.Now)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task UtcNow(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset != DateTimeOffset.UtcNow)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Date(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Date > new DateTimeOffset().Date)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Year(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Year == 1998)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Month(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Month == 5)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task DayOfYear(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.DayOfYear == 124)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Day(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Day == 4)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Hour(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Hour == 15)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Minute(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Minute == 30)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Second(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Second == 10)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Millisecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.DateTimeOffset.Millisecond == 123)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Microsecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(e => e.DateTimeOffset.Microsecond == 456)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Nanosecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(e => e.DateTimeOffset.Nanosecond == 400)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task TimeOfDay(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.TimeOfDay)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddYears(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddYears(1))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddMonths(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddMonths(1))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddDays(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddDays(1))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddHours(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddHours(1))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddMinutes(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddMinutes(1))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddSeconds(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddSeconds(1))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddMilliseconds(bool async) + => AssertQueryScalar( + async, + ss => ss.Set().Select(b => b.DateTimeOffset.AddMilliseconds(300))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToUnixTimeMilliseconds(bool async) + { + var unixEpochMilliseconds = new DateTimeOffset(1998, 5, 4, 15, 30, 10, TimeSpan.Zero).ToUnixTimeMilliseconds(); + + return AssertQuery( + async, + ss => ss.Set() + .Where(b => b.DateTimeOffset.ToUnixTimeMilliseconds() == unixEpochMilliseconds)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task ToUnixTimeSecond(bool async) + { + var unixEpochSeconds = new DateTimeOffset(1998, 5, 4, 15, 30, 10, TimeSpan.Zero).ToUnixTimeSeconds(); + + return AssertQuery( + async, + ss => ss.Set() + .Where(b => b.DateTimeOffset.ToUnixTimeSeconds() == unixEpochSeconds)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Milliseconds_parameter_and_constant(bool async) + { + var dateTimeOffset = new DateTimeOffset(599898024001234567, new TimeSpan(1, 30, 0)); + + // Literal where clause + var p = Expression.Parameter(typeof(BasicTypesEntity), "i"); + var dynamicWhere = Expression.Lambda>( + Expression.Equal( + Expression.Property(p, "DateTimeOffset"), + Expression.Constant(dateTimeOffset) + ), p); + + return AssertCount( + async, + ss => ss.Set().Where(dynamicWhere), + ss => ss.Set().Where(m => m.DateTimeOffset == dateTimeOffset)); + } +} diff --git a/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateTimeTranslationsTestBase.cs b/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateTimeTranslationsTestBase.cs new file mode 100644 index 00000000000..23da35cb4c6 --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/Translations/Temporal/DateTimeTranslationsTestBase.cs @@ -0,0 +1,171 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public abstract class DateTimeTranslationsTestBase(TFixture fixture) : QueryTestBase(fixture) + where TFixture : BasicTypesQueryFixtureBase, new() +{ + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Now(bool async) + { + var myDatetime = new DateTime(2015, 4, 10); + + return AssertQuery( + async, + ss => ss.Set().Where(c => DateTime.Now != myDatetime)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task UtcNow(bool async) + { + var myDatetime = new DateTime(2015, 4, 10); + + return AssertQuery( + async, + ss => ss.Set().Where(c => DateTime.UtcNow != myDatetime)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Today(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(e => e.DateTime == DateTime.Today), + assertEmpty: true); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Date(bool async) + { + var myDatetime = new DateTime(1998, 5, 4); + + return AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Date == myDatetime)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddYear(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.AddYears(1).Year == 1999)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Year(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Year == 1998)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Month(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Month == 5)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task DayOfYear(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.DayOfYear == 124)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Day(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Day == 4)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Hour(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Hour == 15)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Minute(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Minute == 30)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Second(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Second == 10)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Millisecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.Millisecond == 123)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task TimeOfDay(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime.TimeOfDay == TimeSpan.Zero)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task subtract_and_TotalDays(bool async) + { + var date = new DateTime(1997, 1, 1); + + return AssertQuery( + async, + ss => ss.Set().Where(o => (o.DateTime - date).TotalDays > 365)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Parse_with_constant(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime == DateTime.Parse("5/4/1998 15:30:10 PM"))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Parse_with_parameter(bool async) + { + var date = "5/4/1998 15:30:10 PM"; + + return AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime == DateTime.Parse(date))); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task New_with_constant(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime == new DateTime(1998, 5, 4, 15, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task New_with_parameters(bool async) + { + var year = 1998; + var month = 5; + var date = 4; + var hour = 15; + + await AssertQuery( + async, + ss => ss.Set().Where(o => o.DateTime == new DateTime(year, month, date, hour, 30, 10))); + } +} diff --git a/test/EFCore.Specification.Tests/Query/Translations/Temporal/TimeOnlyTranslationsTestBase.cs b/test/EFCore.Specification.Tests/Query/Translations/Temporal/TimeOnlyTranslationsTestBase.cs new file mode 100644 index 00000000000..4c5040d20b0 --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/Translations/Temporal/TimeOnlyTranslationsTestBase.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public abstract class TimeOnlyTranslationsTestBase(TFixture fixture) : QueryTestBase(fixture) + where TFixture : BasicTypesQueryFixtureBase, new() +{ + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Hour(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.Hour == 15)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Minute(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.Minute == 30)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Second(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.Second == 10)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Millisecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.Millisecond == 123)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Microsecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(e => e.TimeOnly.Microsecond == 456)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Nanosecond(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(e => e.TimeOnly.Nanosecond == 400)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddHours(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.AddHours(3) == new TimeOnly(18, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task AddMinutes(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.AddMinutes(3) == new TimeOnly(15, 33, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Add_TimeSpan(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.Add(new TimeSpan(3, 0, 0)) == new TimeOnly(18, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task IsBetween(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly.IsBetween(new TimeOnly(14, 0, 0), new TimeOnly(16, 0, 0)))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Subtract(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeOnly - new TimeOnly(3, 0, 0) == new TimeSpan(12, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromDateTime_compared_to_property(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => TimeOnly.FromDateTime(b.DateTime) == b.TimeOnly)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromDateTime_compared_to_parameter(bool async) + { + var time = new TimeOnly(15, 30, 10); + + return AssertQuery( + async, + ss => ss.Set().Where(b => TimeOnly.FromDateTime(b.DateTime) == time)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromDateTime_compared_to_constant(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => TimeOnly.FromDateTime(b.DateTime) == new TimeOnly(15, 30, 10))); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromTimeSpan_compared_to_property(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => TimeOnly.FromTimeSpan(b.TimeSpan) < b.TimeOnly)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task FromTimeSpan_compared_to_parameter(bool async) + { + var time = new TimeOnly(1, 2, 3); + + return AssertQuery( + async, + ss => ss.Set().Where(x => TimeOnly.FromTimeSpan(x.TimeSpan) == time)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Order_by_FromTimeSpan(bool async) + => AssertQuery( + async, + ss => ss.Set().OrderBy(x => TimeOnly.FromTimeSpan(x.TimeSpan)), + assertOrder: true); +} diff --git a/test/EFCore.Specification.Tests/Query/Translations/Temporal/TimeSpanTranslationsTestBase.cs b/test/EFCore.Specification.Tests/Query/Translations/Temporal/TimeSpanTranslationsTestBase.cs new file mode 100644 index 00000000000..88e9cd4b1e9 --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/Translations/Temporal/TimeSpanTranslationsTestBase.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public abstract class TimeSpanTranslationsTestBase(TFixture fixture) : QueryTestBase(fixture) + where TFixture : BasicTypesQueryFixtureBase, new() +{ + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Hours(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeSpan.Hours == 3)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Minutes(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeSpan.Minutes == 4)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Seconds(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeSpan.Seconds == 5)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Milliseconds(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeSpan.Milliseconds == 678)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Microseconds(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeSpan.Microseconds == 912)); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Nanoseconds(bool async) + => AssertQuery( + async, + ss => ss.Set().Where(b => b.TimeSpan.Nanoseconds == 400)); +} diff --git a/test/EFCore.Specification.Tests/Query/Translations/TemporalTranslationsTestBase.cs b/test/EFCore.Specification.Tests/Query/Translations/TemporalTranslationsTestBase.cs deleted file mode 100644 index 68cfedb82e5..00000000000 --- a/test/EFCore.Specification.Tests/Query/Translations/TemporalTranslationsTestBase.cs +++ /dev/null @@ -1,675 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; - -namespace Microsoft.EntityFrameworkCore.Query.Translations; - -public abstract class TemporalTranslationsTestBase(TFixture fixture) : QueryTestBase(fixture) - where TFixture : BasicTypesQueryFixtureBase, new() -{ - #region DateTime - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Now(bool async) - { - var myDatetime = new DateTime(2015, 4, 10); - - return AssertQuery( - async, - ss => ss.Set().Where(c => DateTime.Now != myDatetime)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_UtcNow(bool async) - { - var myDatetime = new DateTime(2015, 4, 10); - - return AssertQuery( - async, - ss => ss.Set().Where(c => DateTime.UtcNow != myDatetime)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Today(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(e => e.DateTime == DateTime.Today), - assertEmpty: true); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Date(bool async) - { - var myDatetime = new DateTime(1998, 5, 4); - - return AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Date == myDatetime)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_AddYear(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.AddYears(1).Year == 1999)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Year(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Year == 1998)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Month(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Month == 5)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_DayOfYear(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.DayOfYear == 124)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Day(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Day == 4)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Hour(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Hour == 15)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Minute(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Minute == 30)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Second(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Second == 10)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Millisecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.Millisecond == 123)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_TimeOfDay(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime.TimeOfDay == TimeSpan.Zero)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_subtract_and_TotalDays(bool async) - { - var date = new DateTime(1997, 1, 1); - - return AssertQuery( - async, - ss => ss.Set().Where(o => (o.DateTime - date).TotalDays > 365)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Parse_with_constant(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime == DateTime.Parse("5/4/1998 15:30:10 PM"))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_Parse_with_parameter(bool async) - { - var date = "5/4/1998 15:30:10 PM"; - - return AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime == DateTime.Parse(date))); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTime_new_with_constant(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime == new DateTime(1998, 5, 4, 15, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task DateTime_new_with_parameters(bool async) - { - var year = 1998; - var month = 5; - var date = 4; - var hour = 15; - - await AssertQuery( - async, - ss => ss.Set().Where(o => o.DateTime == new DateTime(year, month, date, hour, 30, 10))); - } - - #endregion DateTime - - #region DateOnly - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_Year(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.Year == 1990)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_Month(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.Month == 11)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_Day(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.Day == 10)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_DayOfYear(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.DayOfYear == 314)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_DayOfWeek(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.DayOfWeek == DayOfWeek.Saturday)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_AddYears(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.AddYears(3) == new DateOnly(1993, 11, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_AddMonths(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.AddMonths(3) == new DateOnly(1991, 2, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_AddDays(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateOnly.AddDays(3) == new DateOnly(1990, 11, 13))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_FromDateTime(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => DateOnly.FromDateTime(o.DateTime) == new DateOnly(1998, 5, 4))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_FromDateTime_compared_to_property(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(o => DateOnly.FromDateTime(o.DateTime) == o.DateOnly)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) - { - var dateOnly = new DateOnly(2, 10, 11); - - return AssertQuery( - async, - ss => ss.Set() - .Where(x => new[] { dateOnly, new DateOnly(1998, 5, 4) }.Contains(DateOnly.FromDateTime(x.DateTime)))); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(bool async) - => AssertQuery( - async, - ss => ss.Set() - .Where(o => o.DateOnly.ToDateTime(new TimeOnly(21, 5, 19, 940, 500)) == new DateTime(2020, 1, 1, 21, 5, 19, 940, 500))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(bool async) - => AssertQuery( - async, - ss => ss.Set() - .Where(o => o.DateOnly.ToDateTime(o.TimeOnly) == new DateTime(2020, 1, 1, 15, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) - => AssertQuery( - async, - ss => ss.Set() - .Where(o => new DateOnly(1990, 11, 10).ToDateTime(o.TimeOnly) == new DateTime(1990, 11, 10, 15, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_ToDateTime_with_complex_DateTime(bool async) - => AssertQuery( - async, - ss => ss.Set() - .Where(o => o.DateOnly.AddYears(1).ToDateTime(o.TimeOnly) == new DateTime(2021, 1, 1, 15, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateOnly_ToDateTime_with_complex_TimeOnly(bool async) - => AssertQuery( - async, - ss => ss.Set() - .Where(o => o.DateOnly.ToDateTime(o.TimeOnly.AddHours(1)) == new DateTime(2020, 1, 1, 16, 30, 10)) - .AsTracking()); - - #endregion DateOnly - - #region TimeOnly - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Hour(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.Hour == 15)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Minute(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.Minute == 30)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Second(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.Second == 10)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Millisecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.Millisecond == 123)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Microsecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(e => e.TimeOnly.Microsecond == 456)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Nanosecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(e => e.TimeOnly.Nanosecond == 400)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_AddHours(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.AddHours(3) == new TimeOnly(18, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_AddMinutes(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.AddMinutes(3) == new TimeOnly(15, 33, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_Add_TimeSpan(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.Add(new TimeSpan(3, 0, 0)) == new TimeOnly(18, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_IsBetween(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly.IsBetween(new TimeOnly(14, 0, 0), new TimeOnly(16, 0, 0)))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_subtract_TimeOnly(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeOnly - new TimeOnly(3, 0, 0) == new TimeSpan(12, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_FromDateTime_compared_to_property(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => TimeOnly.FromDateTime(b.DateTime) == b.TimeOnly)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_FromDateTime_compared_to_parameter(bool async) - { - var time = new TimeOnly(15, 30, 10); - - return AssertQuery( - async, - ss => ss.Set().Where(b => TimeOnly.FromDateTime(b.DateTime) == time)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_FromDateTime_compared_to_constant(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => TimeOnly.FromDateTime(b.DateTime) == new TimeOnly(15, 30, 10))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeOnly_FromTimeSpan_compared_to_property(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => TimeOnly.FromTimeSpan(b.TimeSpan) < b.TimeOnly)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task 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.TimeSpan) == time)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task Order_by_TimeOnly_FromTimeSpan(bool async) - => AssertQuery( - async, - ss => ss.Set().OrderBy(x => TimeOnly.FromTimeSpan(x.TimeSpan)), - assertOrder: true); - - #endregion TimeOnly - - #region DateTimeOffset - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Now(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset != DateTimeOffset.Now)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_UtcNow(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset != DateTimeOffset.UtcNow)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Date(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Date > new DateTimeOffset().Date)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Year(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Year == 1998)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Month(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Month == 5)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_DayOfYear(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.DayOfYear == 124)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Day(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Day == 4)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Hour(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Hour == 15)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Minute(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Minute == 30)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Second(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Second == 10)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Millisecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.DateTimeOffset.Millisecond == 123)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Microsecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(e => e.DateTimeOffset.Microsecond == 456)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_Nanosecond(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(e => e.DateTimeOffset.Nanosecond == 400)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_TimeOfDay(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.TimeOfDay)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddYears(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddYears(1))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddMonths(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddMonths(1))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddDays(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddDays(1))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddHours(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddHours(1))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddMinutes(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddMinutes(1))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddSeconds(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddSeconds(1))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_AddMilliseconds(bool async) - => AssertQueryScalar( - async, - ss => ss.Set().Select(b => b.DateTimeOffset.AddMilliseconds(300))); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_ToUnixTimeMilliseconds(bool async) - { - var unixEpochMilliseconds = new DateTimeOffset(1998, 5, 4, 15, 30, 10, TimeSpan.Zero).ToUnixTimeMilliseconds(); - - return AssertQuery( - async, - ss => ss.Set() - .Where(b => b.DateTimeOffset.ToUnixTimeMilliseconds() == unixEpochMilliseconds)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_ToUnixTimeSecond(bool async) - { - var unixEpochSeconds = new DateTimeOffset(1998, 5, 4, 15, 30, 10, TimeSpan.Zero).ToUnixTimeSeconds(); - - return AssertQuery( - async, - ss => ss.Set() - .Where(b => b.DateTimeOffset.ToUnixTimeSeconds() == unixEpochSeconds)); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task DateTimeOffset_milliseconds_parameter_and_constant(bool async) - { - var dateTimeOffset = new DateTimeOffset(599898024001234567, new TimeSpan(1, 30, 0)); - - // Literal where clause - var p = Expression.Parameter(typeof(BasicTypesEntity), "i"); - var dynamicWhere = Expression.Lambda>( - Expression.Equal( - Expression.Property(p, "DateTimeOffset"), - Expression.Constant(dateTimeOffset) - ), p); - - return AssertCount( - async, - ss => ss.Set().Where(dynamicWhere), - ss => ss.Set().Where(m => m.DateTimeOffset == dateTimeOffset)); - } - - #endregion DateTimeOffset - - #region TimeSpan - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeSpan_Hours(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeSpan.Hours == 3)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeSpan_Minutes(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeSpan.Minutes == 4)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeSpan_Seconds(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeSpan.Seconds == 5)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeSpan_Milliseconds(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeSpan.Milliseconds == 678)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeSpan_Microseconds(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeSpan.Microseconds == 912)); - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual Task TimeSpan_Nanoseconds(bool async) - => AssertQuery( - async, - ss => ss.Set().Where(b => b.TimeSpan.Nanoseconds == 400)); - - #endregion TimeSpan -} diff --git a/test/EFCore.Specification.Tests/TestModels/BasicTypesModel/BasicTypesContext.cs b/test/EFCore.Specification.Tests/TestModels/BasicTypesModel/BasicTypesContext.cs index d6778986a5d..7d0d50ec4ae 100644 --- a/test/EFCore.Specification.Tests/TestModels/BasicTypesModel/BasicTypesContext.cs +++ b/test/EFCore.Specification.Tests/TestModels/BasicTypesModel/BasicTypesContext.cs @@ -13,12 +13,4 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity().Property(b => b.Id).ValueGeneratedNever(); modelBuilder.Entity().Property(b => b.Id).ValueGeneratedNever(); } - - public static Task SeedAsync(BasicTypesContext context, bool useGeneratedKeys) - { - context.BasicTypesEntities.AddRange(BasicTypesData.CreateBasicTypesEntities()); - context.NullableBasicTypesEntities.AddRange(BasicTypesData.CreateNullableBasicTypesEntities()); - - return context.SaveChangesAsync(); - } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsSqlServerTest.cs new file mode 100644 index 00000000000..fc1c95b09d3 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsSqlServerTest.cs @@ -0,0 +1,200 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateOnlyTranslationsSqlServerTest : DateOnlyTranslationsTestBase +{ + public DateOnlyTranslationsSqlServerTest(BasicTypesQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Year(bool async) + { + await base.Year(async); + + AssertSql( + """ +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 DATEPART(year, [b].[DateOnly]) = 1990 +"""); + } + + public override async Task Month(bool async) + { + await base.Month(async); + + AssertSql( + """ +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 DATEPART(month, [b].[DateOnly]) = 11 +"""); + } + + public override async Task Day(bool async) + { + await base.Day(async); + + AssertSql( + """ +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 DATEPART(day, [b].[DateOnly]) = 10 +"""); + } + + public override async Task DayOfYear(bool async) + { + await base.DayOfYear(async); + + AssertSql( + """ +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 DATEPART(dayofyear, [b].[DateOnly]) = 314 +"""); + } + + public override async Task DayOfWeek(bool async) + { + await AssertTranslationFailed(() => base.DayOfWeek(async)); + + AssertSql(); + } + + public override async Task AddYears(bool async) + { + await base.AddYears(async); + + AssertSql( + """ +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 DATEADD(year, CAST(3 AS int), [b].[DateOnly]) = '1993-11-10' +"""); + } + + public override async Task AddMonths(bool async) + { + await base.AddMonths(async); + + AssertSql( + """ +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 DATEADD(month, CAST(3 AS int), [b].[DateOnly]) = '1991-02-10' +"""); + } + + public override async Task AddDays(bool async) + { + await base.AddDays(async); + + AssertSql( + """ +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 DATEADD(day, CAST(3 AS int), [b].[DateOnly]) = '1990-11-13' +"""); + } + + public override async Task FromDateTime(bool async) + { + await base.FromDateTime(async); + + AssertSql( + """ +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].[DateTime] AS date) = '1998-05-04' +"""); + } + + public override async Task FromDateTime_compared_to_property(bool async) + { + await base.FromDateTime_compared_to_property(async); + + AssertSql( + """ +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].[DateTime] AS date) = [b].[DateOnly] +"""); + } + + public override async Task FromDateTime_compared_to_constant_and_parameter(bool async) + { + await base.FromDateTime_compared_to_constant_and_parameter(async); + + AssertSql( + """ +@dateOnly='10/11/0002' (DbType = Date) + +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].[DateTime] AS date) IN (@dateOnly, '1998-05-04') +"""); + } + + public override async Task ToDateTime_property_with_constant_TimeOnly(bool async) + { + await base.ToDateTime_property_with_constant_TimeOnly(async); + + AssertSql( + """ +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 DATETIME2FROMPARTS(DATEPART(year, [b].[DateOnly]), DATEPART(month, [b].[DateOnly]), DATEPART(day, [b].[DateOnly]), 21, 5, 19, 9405000, 7) = '2020-01-01T21:05:19.9405000' +"""); + } + + public override async Task ToDateTime_property_with_property_TimeOnly(bool async) + { + await base.ToDateTime_property_with_property_TimeOnly(async); + + AssertSql( + """ +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 DATETIME2FROMPARTS(DATEPART(year, [b].[DateOnly]), DATEPART(month, [b].[DateOnly]), DATEPART(day, [b].[DateOnly]), DATEPART(hour, [b].[TimeOnly]), DATEPART(minute, [b].[TimeOnly]), DATEPART(second, [b].[TimeOnly]), DATEPART(nanosecond, [b].[TimeOnly]) / 100, 7) = '2020-01-01T15:30:10.0000000' +"""); + } + + public override async Task ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) + { + await base.ToDateTime_constant_DateTime_with_property_TimeOnly(async); + + AssertSql( + """ +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 DATETIME2FROMPARTS(1990, 11, 10, DATEPART(hour, [b].[TimeOnly]), DATEPART(minute, [b].[TimeOnly]), DATEPART(second, [b].[TimeOnly]), DATEPART(nanosecond, [b].[TimeOnly]) / 100, 7) = '1990-11-10T15:30:10.0000000' +"""); + } + + public override async Task ToDateTime_with_complex_DateTime(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_with_complex_DateTime(async)); + + AssertSql(); + } + + public override async Task ToDateTime_with_complex_TimeOnly(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_with_complex_TimeOnly(async)); + + AssertSql(); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsSqlServerTest.cs new file mode 100644 index 00000000000..1e46e195150 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsSqlServerTest.cs @@ -0,0 +1,307 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateTimeOffsetTranslationsSqlServerTest : DateTimeOffsetTranslationsTestBase +{ + public DateTimeOffsetTranslationsSqlServerTest(BasicTypesQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Now(bool async) + { + await base.Now(async); + + AssertSql( + """ +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].[DateTimeOffset] <> SYSDATETIMEOFFSET() +"""); + } + + public override async Task UtcNow(bool async) + { + await base.UtcNow(async); + + AssertSql( + """ +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].[DateTimeOffset] <> CAST(SYSUTCDATETIME() AS datetimeoffset) +"""); + } + + public override async Task Date(bool async) + { + await base.Date(async); + + AssertSql( + """ +@Date='0001-01-01T00:00:00.0000000' + +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 CONVERT(date, [b].[DateTimeOffset]) > @Date +"""); + } + + public override async Task Year(bool async) + { + await base.Year(async); + + AssertSql( + """ +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 DATEPART(year, [b].[DateTimeOffset]) = 1998 +"""); + } + + public override async Task Month(bool async) + { + await base.Month(async); + + AssertSql( + """ +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 DATEPART(month, [b].[DateTimeOffset]) = 5 +"""); + } + + public override async Task DayOfYear(bool async) + { + await base.DayOfYear(async); + + AssertSql( + """ +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 DATEPART(dayofyear, [b].[DateTimeOffset]) = 124 +"""); + } + + public override async Task Day(bool async) + { + await base.Day(async); + + AssertSql( + """ +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 DATEPART(day, [b].[DateTimeOffset]) = 4 +"""); + } + + public override async Task Hour(bool async) + { + await base.Hour(async); + + AssertSql( + """ +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 DATEPART(hour, [b].[DateTimeOffset]) = 15 +"""); + } + + public override async Task Minute(bool async) + { + await base.Minute(async); + + AssertSql( + """ +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 DATEPART(minute, [b].[DateTimeOffset]) = 30 +"""); + } + + public override async Task Second(bool async) + { + await base.Second(async); + + AssertSql( + """ +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 DATEPART(second, [b].[DateTimeOffset]) = 10 +"""); + } + + public override async Task Millisecond(bool async) + { + await base.Millisecond(async); + + AssertSql( + """ +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 DATEPART(millisecond, [b].[DateTimeOffset]) = 123 +"""); + } + + public override async Task Microsecond(bool async) + { + await base.Microsecond(async); + + AssertSql( + """ +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 DATEPART(microsecond, [b].[DateTimeOffset]) % 1000 = 456 +"""); + } + + public override async Task Nanosecond(bool async) + { + await base.Nanosecond(async); + + AssertSql( + """ +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 DATEPART(nanosecond, [b].[DateTimeOffset]) % 1000 = 400 +"""); + } + + public override async Task TimeOfDay(bool async) + { + await base.TimeOfDay(async); + + AssertSql( + """ +SELECT CONVERT(time, [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddYears(bool async) + { + await base.AddYears(async); + + AssertSql( + """ +SELECT DATEADD(year, CAST(1 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddMonths(bool async) + { + await base.AddMonths(async); + + AssertSql( + """ +SELECT DATEADD(month, CAST(1 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddDays(bool async) + { + await base.AddDays(async); + + AssertSql( + """ +SELECT DATEADD(day, CAST(1.0E0 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddHours(bool async) + { + await base.AddHours(async); + + AssertSql( + """ +SELECT DATEADD(hour, CAST(1.0E0 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddMinutes(bool async) + { + await base.AddMinutes(async); + + AssertSql( + """ +SELECT DATEADD(minute, CAST(1.0E0 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddSeconds(bool async) + { + await base.AddSeconds(async); + + AssertSql( + """ +SELECT DATEADD(second, CAST(1.0E0 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task AddMilliseconds(bool async) + { + await base.AddMilliseconds(async); + + AssertSql( + """ +SELECT DATEADD(millisecond, CAST(300.0E0 AS int), [b].[DateTimeOffset]) +FROM [BasicTypesEntities] AS [b] +"""); + } + + public override async Task ToUnixTimeMilliseconds(bool async) + { + await base.ToUnixTimeMilliseconds(async); + + AssertSql( + """ +@unixEpochMilliseconds='894295810000' + +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 DATEDIFF_BIG(millisecond, '1970-01-01T00:00:00.0000000+00:00', [b].[DateTimeOffset]) = @unixEpochMilliseconds +"""); + } + + public override async Task ToUnixTimeSecond(bool async) + { + await base.ToUnixTimeSecond(async); + + AssertSql( + """ +@unixEpochSeconds='894295810' + +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 DATEDIFF_BIG(second, '1970-01-01T00:00:00.0000000+00:00', [b].[DateTimeOffset]) = @unixEpochSeconds +"""); + } + + public override async Task Milliseconds_parameter_and_constant(bool async) + { + await base.Milliseconds_parameter_and_constant(async); + + AssertSql( + """ +SELECT COUNT(*) +FROM [BasicTypesEntities] AS [b] +WHERE [b].[DateTimeOffset] = '1902-01-02T10:00:00.1234567+01:30' +"""); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsSqlServerTest.cs new file mode 100644 index 00000000000..24900ee72f4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsSqlServerTest.cs @@ -0,0 +1,250 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateTimeTranslationsSqlServerTest : DateTimeTranslationsTestBase +{ + public DateTimeTranslationsSqlServerTest(BasicTypesQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Now(bool async) + { + await base.Now(async); + + AssertSql( + """ +@myDatetime='2015-04-10T00:00:00.0000000' + +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 GETDATE() <> @myDatetime +"""); + } + + public override async Task UtcNow(bool async) + { + await base.UtcNow(async); + + AssertSql( + """ +@myDatetime='2015-04-10T00:00:00.0000000' + +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 GETUTCDATE() <> @myDatetime +"""); + } + + public override async Task Today(bool async) + { + await base.Today(async); + + AssertSql( + """ +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].[DateTime] = CONVERT(date, GETDATE()) +"""); + } + + public override async Task Date(bool async) + { + await base.Date(async); + + AssertSql( + """ +@myDatetime='1998-05-04T00:00:00.0000000' + +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 CONVERT(date, [b].[DateTime]) = @myDatetime +"""); + } + + public override async Task AddYear(bool async) + { + await base.AddYear(async); + + AssertSql( + """ +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 DATEPART(year, DATEADD(year, CAST(1 AS int), [b].[DateTime])) = 1999 +"""); + } + + public override async Task Year(bool async) + { + await base.Year(async); + + AssertSql( + """ +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 DATEPART(year, [b].[DateTime]) = 1998 +"""); + } + + public override async Task Month(bool async) + { + await base.Month(async); + + AssertSql( + """ +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 DATEPART(month, [b].[DateTime]) = 5 +"""); + } + + public override async Task DayOfYear(bool async) + { + await base.DayOfYear(async); + + AssertSql( + """ +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 DATEPART(dayofyear, [b].[DateTime]) = 124 +"""); + } + + public override async Task Day(bool async) + { + await base.Day(async); + + AssertSql( + """ +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 DATEPART(day, [b].[DateTime]) = 4 +"""); + } + + public override async Task Hour(bool async) + { + await base.Hour(async); + + AssertSql( + """ +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 DATEPART(hour, [b].[DateTime]) = 15 +"""); + } + + public override async Task Minute(bool async) + { + await base.Minute(async); + + AssertSql( + """ +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 DATEPART(minute, [b].[DateTime]) = 30 +"""); + } + + public override async Task Second(bool async) + { + await base.Second(async); + + AssertSql( + """ +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 DATEPART(second, [b].[DateTime]) = 10 +"""); + } + + public override async Task Millisecond(bool async) + { + await base.Millisecond(async); + + AssertSql( + """ +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 DATEPART(millisecond, [b].[DateTime]) = 123 +"""); + } + + public override async Task TimeOfDay(bool async) + { + await base.TimeOfDay(async); + + AssertSql( + """ +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 CONVERT(time, [b].[DateTime]) = '00:00:00' +"""); + } + + public override Task subtract_and_TotalDays(bool async) + => AssertTranslationFailed(() => base.subtract_and_TotalDays(async)); + + public override async Task Parse_with_constant(bool async) + { + await base.Parse_with_constant(async); + + AssertSql( + """ +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].[DateTime] = '1998-05-04T15:30:10.0000000' +"""); + } + + public override async Task Parse_with_parameter(bool async) + { + await base.Parse_with_parameter(async); + + AssertSql( + """ +@Parse='1998-05-04T15:30:10.0000000' + +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].[DateTime] = @Parse +"""); + } + + public override async Task New_with_constant(bool async) + { + await base.New_with_constant(async); + + AssertSql( + """ +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].[DateTime] = '1998-05-04T15:30:10.0000000' +"""); + } + + public override async Task New_with_parameters(bool async) + { + await base.New_with_parameters(async); + + AssertSql( + """ +@p='1998-05-04T15:30:10.0000000' + +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].[DateTime] = @p +"""); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs new file mode 100644 index 00000000000..ed7e9fa94a4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqlServerTest.cs @@ -0,0 +1,225 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class TimeOnlyTranslationsSqlServerTest : TimeOnlyTranslationsTestBase +{ + public TimeOnlyTranslationsSqlServerTest(BasicTypesQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Hour(bool async) + { + await base.Hour(async); + + AssertSql( + """ +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 DATEPART(hour, [b].[TimeOnly]) = 15 +"""); + } + + public override async Task Minute(bool async) + { + await base.Minute(async); + + AssertSql( + """ +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 DATEPART(minute, [b].[TimeOnly]) = 30 +"""); + } + + public override async Task Second(bool async) + { + await base.Second(async); + + AssertSql( + """ +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 DATEPART(second, [b].[TimeOnly]) = 10 +"""); + } + + public override async Task Millisecond(bool async) + { + await base.Millisecond(async); + + AssertSql( + """ +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 DATEPART(millisecond, [b].[TimeOnly]) = 123 +"""); + } + + public override async Task Microsecond(bool async) + { + await base.Microsecond(async); + + AssertSql( + """ +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 DATEPART(microsecond, [b].[TimeOnly]) % 1000 = 456 +"""); + } + + public override async Task Nanosecond(bool async) + { + await base.Nanosecond(async); + + AssertSql( + """ +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 DATEPART(nanosecond, [b].[TimeOnly]) % 1000 = 400 +"""); + } + + public override async Task AddHours(bool async) + { + await base.AddHours(async); + + AssertSql( + """ +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 DATEADD(hour, CAST(3.0E0 AS int), [b].[TimeOnly]) = '18:30:10' +"""); + } + + public override async Task AddMinutes(bool async) + { + await base.AddMinutes(async); + + AssertSql( + """ +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 DATEADD(minute, CAST(3.0E0 AS int), [b].[TimeOnly]) = '15:33:10' +"""); + } + + public override async Task Add_TimeSpan(bool async) + { + await AssertTranslationFailed(() => base.Add_TimeSpan(async)); + + AssertSql(); + } + + public override async Task IsBetween(bool async) + { + await base.IsBetween(async); + + AssertSql( + """ +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 CASE + WHEN [b].[TimeOnly] >= '14:00:00' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END & CASE + WHEN [b].[TimeOnly] < '16:00:00' THEN CAST(1 AS bit) + ELSE CAST(0 AS bit) +END = CAST(1 AS bit) +"""); + } + + public override async Task Subtract(bool async) + { + await AssertTranslationFailed(() => base.Subtract(async)); + + AssertSql(); + } + + public override async Task FromDateTime_compared_to_property(bool async) + { + await base.FromDateTime_compared_to_property(async); + + AssertSql( + """ +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].[DateTime] AS time) = [b].[TimeOnly] +"""); + } + + public override async Task FromDateTime_compared_to_parameter(bool async) + { + await base.FromDateTime_compared_to_parameter(async); + + AssertSql( + """ +@time='15:30' (DbType = Time) + +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].[DateTime] AS time) = @time +"""); + } + + public override async Task FromDateTime_compared_to_constant(bool async) + { + await base.FromDateTime_compared_to_constant(async); + + AssertSql( + """ +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].[DateTime] AS time) = '15:30:10' +"""); + } + + public override async Task FromTimeSpan_compared_to_property(bool async) + { + await base.FromTimeSpan_compared_to_property(async); + + AssertSql( + """ +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] +"""); + } + + public override async Task FromTimeSpan_compared_to_parameter(bool async) + { + await base.FromTimeSpan_compared_to_parameter(async); + + AssertSql( + """ +@time='01:02' (DbType = Time) + +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 +"""); + } + + public override async Task Order_by_FromTimeSpan(bool async) + { + await base.Order_by_FromTimeSpan(async); + + AssertSql( + """ +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) +"""); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsSqlServerTest.cs new file mode 100644 index 00000000000..1152d2cd0d4 --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsSqlServerTest.cs @@ -0,0 +1,93 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class TimeSpanTranslationsSqlServerTest : TimeSpanTranslationsTestBase +{ + public TimeSpanTranslationsSqlServerTest(BasicTypesQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Hours(bool async) + { + await base.Hours(async); + + AssertSql( + """ +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 DATEPART(hour, [b].[TimeSpan]) = 3 +"""); + } + + public override async Task Minutes(bool async) + { + await base.Minutes(async); + + AssertSql( + """ +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 DATEPART(minute, [b].[TimeSpan]) = 4 +"""); + } + + public override async Task Seconds(bool async) + { + await base.Seconds(async); + + AssertSql( + """ +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 DATEPART(second, [b].[TimeSpan]) = 5 +"""); + } + + public override async Task Milliseconds(bool async) + { + await base.Milliseconds(async); + + AssertSql( + """ +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 DATEPART(millisecond, [b].[TimeSpan]) = 678 +"""); + } + + public override async Task Microseconds(bool async) + { + await base.Microseconds(async); + + AssertSql( + """ +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 DATEPART(microsecond, [b].[TimeSpan]) % 1000 = 912 +"""); + } + + public override async Task Nanoseconds(bool async) + { + await base.Nanoseconds(async); + + AssertSql( + """ +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 DATEPART(nanosecond, [b].[TimeSpan]) % 1000 = 400 +"""); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/TemporalTranslationsSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/Translations/TemporalTranslationsSqlServerTest.cs deleted file mode 100644 index 4748c20c60a..00000000000 --- a/test/EFCore.SqlServer.FunctionalTests/Query/Translations/TemporalTranslationsSqlServerTest.cs +++ /dev/null @@ -1,1011 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.EntityFrameworkCore.Query.Translations; - -public class TemporalTranslationsSqlServerTest : TemporalTranslationsTestBase -{ - public TemporalTranslationsSqlServerTest(BasicTypesQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) - : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } - - #region DateTime - - public override async Task DateTime_Now(bool async) - { - await base.DateTime_Now(async); - - AssertSql( - """ -@myDatetime='2015-04-10T00:00:00.0000000' - -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 GETDATE() <> @myDatetime -"""); - } - - public override async Task DateTime_UtcNow(bool async) - { - await base.DateTime_UtcNow(async); - - AssertSql( - """ -@myDatetime='2015-04-10T00:00:00.0000000' - -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 GETUTCDATE() <> @myDatetime -"""); - } - - public override async Task DateTime_Today(bool async) - { - await base.DateTime_Today(async); - - AssertSql( - """ -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].[DateTime] = CONVERT(date, GETDATE()) -"""); - } - - public override async Task DateTime_Date(bool async) - { - await base.DateTime_Date(async); - - AssertSql( - """ -@myDatetime='1998-05-04T00:00:00.0000000' - -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 CONVERT(date, [b].[DateTime]) = @myDatetime -"""); - } - - public override async Task DateTime_AddYear(bool async) - { - await base.DateTime_AddYear(async); - - AssertSql( - """ -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 DATEPART(year, DATEADD(year, CAST(1 AS int), [b].[DateTime])) = 1999 -"""); - } - - public override async Task DateTime_Year(bool async) - { - await base.DateTime_Year(async); - - AssertSql( - """ -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 DATEPART(year, [b].[DateTime]) = 1998 -"""); - } - - public override async Task DateTime_Month(bool async) - { - await base.DateTime_Month(async); - - AssertSql( - """ -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 DATEPART(month, [b].[DateTime]) = 5 -"""); - } - - public override async Task DateTime_DayOfYear(bool async) - { - await base.DateTime_DayOfYear(async); - - AssertSql( - """ -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 DATEPART(dayofyear, [b].[DateTime]) = 124 -"""); - } - - public override async Task DateTime_Day(bool async) - { - await base.DateTime_Day(async); - - AssertSql( - """ -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 DATEPART(day, [b].[DateTime]) = 4 -"""); - } - - public override async Task DateTime_Hour(bool async) - { - await base.DateTime_Hour(async); - - AssertSql( - """ -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 DATEPART(hour, [b].[DateTime]) = 15 -"""); - } - - public override async Task DateTime_Minute(bool async) - { - await base.DateTime_Minute(async); - - AssertSql( - """ -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 DATEPART(minute, [b].[DateTime]) = 30 -"""); - } - - public override async Task DateTime_Second(bool async) - { - await base.DateTime_Second(async); - - AssertSql( - """ -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 DATEPART(second, [b].[DateTime]) = 10 -"""); - } - - public override async Task DateTime_Millisecond(bool async) - { - await base.DateTime_Millisecond(async); - - AssertSql( - """ -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 DATEPART(millisecond, [b].[DateTime]) = 123 -"""); - } - - public override async Task DateTime_TimeOfDay(bool async) - { - await base.DateTime_TimeOfDay(async); - - AssertSql( - """ -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 CONVERT(time, [b].[DateTime]) = '00:00:00' -"""); - } - - public override Task DateTime_subtract_and_TotalDays(bool async) - => AssertTranslationFailed(() => base.DateTime_subtract_and_TotalDays(async)); - - public override async Task DateTime_Parse_with_constant(bool async) - { - await base.DateTime_Parse_with_constant(async); - - AssertSql( - """ -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].[DateTime] = '1998-05-04T15:30:10.0000000' -"""); - } - - public override async Task DateTime_Parse_with_parameter(bool async) - { - await base.DateTime_Parse_with_parameter(async); - - AssertSql( - """ -@Parse='1998-05-04T15:30:10.0000000' - -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].[DateTime] = @Parse -"""); - } - - public override async Task DateTime_new_with_constant(bool async) - { - await base.DateTime_new_with_constant(async); - - AssertSql( - """ -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].[DateTime] = '1998-05-04T15:30:10.0000000' -"""); - } - - public override async Task DateTime_new_with_parameters(bool async) - { - await base.DateTime_new_with_parameters(async); - - AssertSql( - """ -@p='1998-05-04T15:30:10.0000000' - -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].[DateTime] = @p -"""); - } - - #endregion DateTime - - #region DateOnly - - public override async Task DateOnly_Year(bool async) - { - await base.DateOnly_Year(async); - - AssertSql( - """ -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 DATEPART(year, [b].[DateOnly]) = 1990 -"""); - } - - public override async Task DateOnly_Month(bool async) - { - await base.DateOnly_Month(async); - - AssertSql( - """ -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 DATEPART(month, [b].[DateOnly]) = 11 -"""); - } - - public override async Task DateOnly_Day(bool async) - { - await base.DateOnly_Day(async); - - AssertSql( - """ -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 DATEPART(day, [b].[DateOnly]) = 10 -"""); - } - - public override async Task DateOnly_DayOfYear(bool async) - { - await base.DateOnly_DayOfYear(async); - - AssertSql( - """ -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 DATEPART(dayofyear, [b].[DateOnly]) = 314 -"""); - } - - public override async Task DateOnly_DayOfWeek(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_DayOfWeek(async)); - - AssertSql(); - } - - public override async Task DateOnly_AddYears(bool async) - { - await base.DateOnly_AddYears(async); - - AssertSql( - """ -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 DATEADD(year, CAST(3 AS int), [b].[DateOnly]) = '1993-11-10' -"""); - } - - public override async Task DateOnly_AddMonths(bool async) - { - await base.DateOnly_AddMonths(async); - - AssertSql( - """ -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 DATEADD(month, CAST(3 AS int), [b].[DateOnly]) = '1991-02-10' -"""); - } - - public override async Task DateOnly_AddDays(bool async) - { - await base.DateOnly_AddDays(async); - - AssertSql( - """ -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 DATEADD(day, CAST(3 AS int), [b].[DateOnly]) = '1990-11-13' -"""); - } - - public override async Task DateOnly_FromDateTime(bool async) - { - await base.DateOnly_FromDateTime(async); - - AssertSql( - """ -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].[DateTime] AS date) = '1998-05-04' -"""); - } - - public override async Task DateOnly_FromDateTime_compared_to_property(bool async) - { - await base.DateOnly_FromDateTime_compared_to_property(async); - - AssertSql( - """ -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].[DateTime] AS date) = [b].[DateOnly] -"""); - } - - public override async Task DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) - { - await base.DateOnly_FromDateTime_compared_to_constant_and_parameter(async); - - AssertSql( - """ -@dateOnly='10/11/0002' (DbType = Date) - -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].[DateTime] AS date) IN (@dateOnly, '1998-05-04') -"""); - } - - public override async Task DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(bool async) - { - await base.DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(async); - - AssertSql( - """ -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 DATETIME2FROMPARTS(DATEPART(year, [b].[DateOnly]), DATEPART(month, [b].[DateOnly]), DATEPART(day, [b].[DateOnly]), 21, 5, 19, 9405000, 7) = '2020-01-01T21:05:19.9405000' -"""); - } - - public override async Task DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(bool async) - { - await base.DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(async); - - AssertSql( - """ -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 DATETIME2FROMPARTS(DATEPART(year, [b].[DateOnly]), DATEPART(month, [b].[DateOnly]), DATEPART(day, [b].[DateOnly]), DATEPART(hour, [b].[TimeOnly]), DATEPART(minute, [b].[TimeOnly]), DATEPART(second, [b].[TimeOnly]), DATEPART(nanosecond, [b].[TimeOnly]) / 100, 7) = '2020-01-01T15:30:10.0000000' -"""); - } - - public override async Task DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) - { - await base.DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(async); - - AssertSql( - """ -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 DATETIME2FROMPARTS(1990, 11, 10, DATEPART(hour, [b].[TimeOnly]), DATEPART(minute, [b].[TimeOnly]), DATEPART(second, [b].[TimeOnly]), DATEPART(nanosecond, [b].[TimeOnly]) / 100, 7) = '1990-11-10T15:30:10.0000000' -"""); - } - - public override async Task DateOnly_ToDateTime_with_complex_DateTime(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_with_complex_DateTime(async)); - - AssertSql(); - } - - public override async Task DateOnly_ToDateTime_with_complex_TimeOnly(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_with_complex_TimeOnly(async)); - - AssertSql(); - } - - #endregion DateOnly - - #region TimeOnly - - public override async Task TimeOnly_Hour(bool async) - { - await base.TimeOnly_Hour(async); - - AssertSql( - """ -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 DATEPART(hour, [b].[TimeOnly]) = 15 -"""); - } - - public override async Task TimeOnly_Minute(bool async) - { - await base.TimeOnly_Minute(async); - - AssertSql( - """ -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 DATEPART(minute, [b].[TimeOnly]) = 30 -"""); - } - - public override async Task TimeOnly_Second(bool async) - { - await base.TimeOnly_Second(async); - - AssertSql( - """ -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 DATEPART(second, [b].[TimeOnly]) = 10 -"""); - } - - public override async Task TimeOnly_Millisecond(bool async) - { - await base.TimeOnly_Millisecond(async); - - AssertSql( - """ -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 DATEPART(millisecond, [b].[TimeOnly]) = 123 -"""); - } - - public override async Task TimeOnly_Microsecond(bool async) - { - await base.TimeOnly_Microsecond(async); - - AssertSql( - """ -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 DATEPART(microsecond, [b].[TimeOnly]) % 1000 = 456 -"""); - } - - public override async Task TimeOnly_Nanosecond(bool async) - { - await base.TimeOnly_Nanosecond(async); - - AssertSql( - """ -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 DATEPART(nanosecond, [b].[TimeOnly]) % 1000 = 400 -"""); - } - - public override async Task TimeOnly_AddHours(bool async) - { - await base.TimeOnly_AddHours(async); - - AssertSql( - """ -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 DATEADD(hour, CAST(3.0E0 AS int), [b].[TimeOnly]) = '18:30:10' -"""); - } - - public override async Task TimeOnly_AddMinutes(bool async) - { - await base.TimeOnly_AddMinutes(async); - - AssertSql( - """ -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 DATEADD(minute, CAST(3.0E0 AS int), [b].[TimeOnly]) = '15:33:10' -"""); - } - - public override async Task TimeOnly_Add_TimeSpan(bool async) - { - await AssertTranslationFailed(() => base.TimeOnly_Add_TimeSpan(async)); - - AssertSql(); - } - - public override async Task TimeOnly_IsBetween(bool async) - { - await base.TimeOnly_IsBetween(async); - - AssertSql( - """ -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 CASE - WHEN [b].[TimeOnly] >= '14:00:00' THEN CAST(1 AS bit) - ELSE CAST(0 AS bit) -END & CASE - WHEN [b].[TimeOnly] < '16:00:00' THEN CAST(1 AS bit) - ELSE CAST(0 AS bit) -END = CAST(1 AS bit) -"""); - } - - public override async Task TimeOnly_subtract_TimeOnly(bool async) - { - await AssertTranslationFailed(() => base.TimeOnly_subtract_TimeOnly(async)); - - AssertSql(); - } - - public override async Task TimeOnly_FromDateTime_compared_to_property(bool async) - { - await base.TimeOnly_FromDateTime_compared_to_property(async); - - AssertSql( - """ -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].[DateTime] AS time) = [b].[TimeOnly] -"""); - } - - public override async Task TimeOnly_FromDateTime_compared_to_parameter(bool async) - { - await base.TimeOnly_FromDateTime_compared_to_parameter(async); - - AssertSql( - """ -@time='15:30' (DbType = Time) - -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].[DateTime] AS time) = @time -"""); - } - - public override async Task TimeOnly_FromDateTime_compared_to_constant(bool async) - { - await base.TimeOnly_FromDateTime_compared_to_constant(async); - - AssertSql( - """ -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].[DateTime] AS time) = '15:30:10' -"""); - } - - public override async Task TimeOnly_FromTimeSpan_compared_to_property(bool async) - { - await base.TimeOnly_FromTimeSpan_compared_to_property(async); - - AssertSql( - """ -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] -"""); - } - - public override async Task TimeOnly_FromTimeSpan_compared_to_parameter(bool async) - { - await base.TimeOnly_FromTimeSpan_compared_to_parameter(async); - - AssertSql( - """ -@time='01:02' (DbType = Time) - -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 -"""); - } - - public override async Task Order_by_TimeOnly_FromTimeSpan(bool async) - { - await base.Order_by_TimeOnly_FromTimeSpan(async); - - AssertSql( - """ -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) -"""); - } - - #endregion TimeOnly - - #region DateTimeOffset - - public override async Task DateTimeOffset_Now(bool async) - { - await base.DateTimeOffset_Now(async); - - AssertSql( - """ -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].[DateTimeOffset] <> SYSDATETIMEOFFSET() -"""); - } - - public override async Task DateTimeOffset_UtcNow(bool async) - { - await base.DateTimeOffset_UtcNow(async); - - AssertSql( - """ -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].[DateTimeOffset] <> CAST(SYSUTCDATETIME() AS datetimeoffset) -"""); - } - - public override async Task DateTimeOffset_Date(bool async) - { - await base.DateTimeOffset_Date(async); - - AssertSql( - """ -@Date='0001-01-01T00:00:00.0000000' - -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 CONVERT(date, [b].[DateTimeOffset]) > @Date -"""); - } - - public override async Task DateTimeOffset_Year(bool async) - { - await base.DateTimeOffset_Year(async); - - AssertSql( - """ -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 DATEPART(year, [b].[DateTimeOffset]) = 1998 -"""); - } - - public override async Task DateTimeOffset_Month(bool async) - { - await base.DateTimeOffset_Month(async); - - AssertSql( - """ -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 DATEPART(month, [b].[DateTimeOffset]) = 5 -"""); - } - - public override async Task DateTimeOffset_DayOfYear(bool async) - { - await base.DateTimeOffset_DayOfYear(async); - - AssertSql( - """ -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 DATEPART(dayofyear, [b].[DateTimeOffset]) = 124 -"""); - } - - public override async Task DateTimeOffset_Day(bool async) - { - await base.DateTimeOffset_Day(async); - - AssertSql( - """ -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 DATEPART(day, [b].[DateTimeOffset]) = 4 -"""); - } - - public override async Task DateTimeOffset_Hour(bool async) - { - await base.DateTimeOffset_Hour(async); - - AssertSql( - """ -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 DATEPART(hour, [b].[DateTimeOffset]) = 15 -"""); - } - - public override async Task DateTimeOffset_Minute(bool async) - { - await base.DateTimeOffset_Minute(async); - - AssertSql( - """ -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 DATEPART(minute, [b].[DateTimeOffset]) = 30 -"""); - } - - public override async Task DateTimeOffset_Second(bool async) - { - await base.DateTimeOffset_Second(async); - - AssertSql( - """ -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 DATEPART(second, [b].[DateTimeOffset]) = 10 -"""); - } - - public override async Task DateTimeOffset_Millisecond(bool async) - { - await base.DateTimeOffset_Millisecond(async); - - AssertSql( - """ -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 DATEPART(millisecond, [b].[DateTimeOffset]) = 123 -"""); - } - - public override async Task DateTimeOffset_Microsecond(bool async) - { - await base.DateTimeOffset_Microsecond(async); - - AssertSql( - """ -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 DATEPART(microsecond, [b].[DateTimeOffset]) % 1000 = 456 -"""); - } - - public override async Task DateTimeOffset_Nanosecond(bool async) - { - await base.DateTimeOffset_Nanosecond(async); - - AssertSql( - """ -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 DATEPART(nanosecond, [b].[DateTimeOffset]) % 1000 = 400 -"""); - } - - public override async Task DateTimeOffset_TimeOfDay(bool async) - { - await base.DateTimeOffset_TimeOfDay(async); - - AssertSql( - """ -SELECT CONVERT(time, [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddYears(bool async) - { - await base.DateTimeOffset_AddYears(async); - - AssertSql( - """ -SELECT DATEADD(year, CAST(1 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddMonths(bool async) - { - await base.DateTimeOffset_AddMonths(async); - - AssertSql( - """ -SELECT DATEADD(month, CAST(1 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddDays(bool async) - { - await base.DateTimeOffset_AddDays(async); - - AssertSql( - """ -SELECT DATEADD(day, CAST(1.0E0 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddHours(bool async) - { - await base.DateTimeOffset_AddHours(async); - - AssertSql( - """ -SELECT DATEADD(hour, CAST(1.0E0 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddMinutes(bool async) - { - await base.DateTimeOffset_AddMinutes(async); - - AssertSql( - """ -SELECT DATEADD(minute, CAST(1.0E0 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddSeconds(bool async) - { - await base.DateTimeOffset_AddSeconds(async); - - AssertSql( - """ -SELECT DATEADD(second, CAST(1.0E0 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_AddMilliseconds(bool async) - { - await base.DateTimeOffset_AddMilliseconds(async); - - AssertSql( - """ -SELECT DATEADD(millisecond, CAST(300.0E0 AS int), [b].[DateTimeOffset]) -FROM [BasicTypesEntities] AS [b] -"""); - } - - public override async Task DateTimeOffset_ToUnixTimeMilliseconds(bool async) - { - await base.DateTimeOffset_ToUnixTimeMilliseconds(async); - - AssertSql( - """ -@unixEpochMilliseconds='894295810000' - -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 DATEDIFF_BIG(millisecond, '1970-01-01T00:00:00.0000000+00:00', [b].[DateTimeOffset]) = @unixEpochMilliseconds -"""); - } - - public override async Task DateTimeOffset_ToUnixTimeSecond(bool async) - { - await base.DateTimeOffset_ToUnixTimeSecond(async); - - AssertSql( - """ -@unixEpochSeconds='894295810' - -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 DATEDIFF_BIG(second, '1970-01-01T00:00:00.0000000+00:00', [b].[DateTimeOffset]) = @unixEpochSeconds -"""); - } - - public override async Task DateTimeOffset_milliseconds_parameter_and_constant(bool async) - { - await base.DateTimeOffset_milliseconds_parameter_and_constant(async); - - AssertSql( - """ -SELECT COUNT(*) -FROM [BasicTypesEntities] AS [b] -WHERE [b].[DateTimeOffset] = '1902-01-02T10:00:00.1234567+01:30' -"""); - } - - #endregion DateTimeOffset - - #region TimeSpan - - public override async Task TimeSpan_Hours(bool async) - { - await base.TimeSpan_Hours(async); - - AssertSql( - """ -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 DATEPART(hour, [b].[TimeSpan]) = 3 -"""); - } - - public override async Task TimeSpan_Minutes(bool async) - { - await base.TimeSpan_Minutes(async); - - AssertSql( - """ -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 DATEPART(minute, [b].[TimeSpan]) = 4 -"""); - } - - public override async Task TimeSpan_Seconds(bool async) - { - await base.TimeSpan_Seconds(async); - - AssertSql( - """ -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 DATEPART(second, [b].[TimeSpan]) = 5 -"""); - } - - public override async Task TimeSpan_Milliseconds(bool async) - { - await base.TimeSpan_Milliseconds(async); - - AssertSql( - """ -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 DATEPART(millisecond, [b].[TimeSpan]) = 678 -"""); - } - - public override async Task TimeSpan_Microseconds(bool async) - { - await base.TimeSpan_Microseconds(async); - - AssertSql( - """ -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 DATEPART(microsecond, [b].[TimeSpan]) % 1000 = 912 -"""); - } - - public override async Task TimeSpan_Nanoseconds(bool async) - { - await base.TimeSpan_Nanoseconds(async); - - AssertSql( - """ -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 DATEPART(nanosecond, [b].[TimeSpan]) % 1000 = 400 -"""); - } - - #endregion TimeSpan - - [ConditionalFact] - public virtual void Check_all_tests_overridden() - => TestHelpers.AssertAllMethodsOverridden(GetType()); - - private void AssertSql(params string[] expected) - => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); -} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsSqliteTest.cs new file mode 100644 index 00000000000..3bdcb857ba0 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateOnlyTranslationsSqliteTest.cs @@ -0,0 +1,224 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateOnlyTranslationsSqliteTest : DateOnlyTranslationsTestBase +{ + public DateOnlyTranslationsSqliteTest(BasicTypesQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Year(bool async) + { + await base.Year(async); + + AssertSql( + """ +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(strftime('%Y', "b"."DateOnly") AS INTEGER) = 1990 +"""); + } + + public override async Task Month(bool async) + { + await base.Month(async); + + AssertSql( + """ +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(strftime('%m', "b"."DateOnly") AS INTEGER) = 11 +"""); + } + + public override async Task Day(bool async) + { + await base.Day(async); + + AssertSql( + """ +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(strftime('%d', "b"."DateOnly") AS INTEGER) = 10 +"""); + } + + public override async Task DayOfYear(bool async) + { + await base.DayOfYear(async); + + AssertSql( + """ +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(strftime('%j', "b"."DateOnly") AS INTEGER) = 314 +"""); + } + + public override async Task DayOfWeek(bool async) + { + await base.DayOfWeek(async); + + AssertSql( + """ +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(strftime('%w', "b"."DateOnly") AS INTEGER) = 6 +"""); + } + + public override async Task AddYears(bool async) + { + await base.AddYears(async); + + AssertSql( + """ +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 date("b"."DateOnly", CAST(3 AS TEXT) || ' years') = '1993-11-10' +"""); + } + + public override async Task AddMonths(bool async) + { + await base.AddMonths(async); + + AssertSql( + """ +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 date("b"."DateOnly", CAST(3 AS TEXT) || ' months') = '1991-02-10' +"""); + } + + public override async Task AddDays(bool async) + { + await base.AddDays(async); + + AssertSql( + """ +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 date("b"."DateOnly", CAST(3 AS TEXT) || ' days') = '1990-11-13' +"""); + } + + public override async Task FromDateTime(bool async) + { + await base.FromDateTime(async); + + AssertSql( + """ +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 date("b"."DateTime") = '1998-05-04' +"""); + } + + public override async Task FromDateTime_compared_to_property(bool async) + { + await base.FromDateTime_compared_to_property(async); + + AssertSql( + """ +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 date("b"."DateTime") = "b"."DateOnly" +"""); + } + + public override async Task FromDateTime_compared_to_constant_and_parameter(bool async) + { + await base.FromDateTime_compared_to_constant_and_parameter(async); + + AssertSql( + """ +@dateOnly='10/11/0002' (DbType = Date) + +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 date("b"."DateTime") IN (@dateOnly, '1998-05-04') +"""); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Where_AddYears_Year(bool async) + { + await AssertQuery( + async, + ss => ss.Set().Where(m => m.DateOnly.AddYears(3).Year == 1993)); + + AssertSql( + """ +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(strftime('%Y', "b"."DateOnly", CAST(3 AS TEXT) || ' years') AS INTEGER) = 1993 +"""); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Where_AddYears_AddMonths(bool async) + { + await AssertQuery( + async, + ss => ss.Set().Where(m => m.DateOnly.AddYears(3).AddMonths(3) == new DateOnly(1994, 2, 10))); + + AssertSql( + """ +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 date("b"."DateOnly", CAST(3 AS TEXT) || ' years', CAST(3 AS TEXT) || ' months') = '1994-02-10' +"""); + } + + public override async Task ToDateTime_property_with_constant_TimeOnly(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_property_with_constant_TimeOnly(async)); + + AssertSql(); + } + + public override async Task ToDateTime_property_with_property_TimeOnly(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_property_with_property_TimeOnly(async)); + + AssertSql(); + } + + public override async Task ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_constant_DateTime_with_property_TimeOnly(async)); + + AssertSql(); + } + + public override async Task ToDateTime_with_complex_DateTime(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_with_complex_DateTime(async)); + + AssertSql(); + } + + public override async Task ToDateTime_with_complex_TimeOnly(bool async) + { + await AssertTranslationFailed(() => base.ToDateTime_with_complex_TimeOnly(async)); + + AssertSql(); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsSqliteTest.cs new file mode 100644 index 00000000000..646645f7247 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateTimeOffsetTranslationsSqliteTest.cs @@ -0,0 +1,218 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateTimeOffsetTranslationsSqliteTest : DateTimeOffsetTranslationsTestBase +{ + public DateTimeOffsetTranslationsSqliteTest(BasicTypesQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Now(bool async) + { + await AssertTranslationFailed(() => base.Now(async)); + + AssertSql(); + } + + public override async Task UtcNow(bool async) + { + await AssertTranslationFailed(() => base.UtcNow(async)); + + AssertSql(); + } + + public override async Task Date(bool async) + { + await AssertTranslationFailed(() => base.Date(async)); + + AssertSql(); + } + + public override async Task Year(bool async) + { + await AssertTranslationFailed(() => base.Year(async)); + + AssertSql(); + } + + public override async Task Month(bool async) + { + await AssertTranslationFailed(() => base.Month(async)); + + AssertSql(); + } + + public override async Task DayOfYear(bool async) + { + await AssertTranslationFailed(() => base.DayOfYear(async)); + + AssertSql(); + } + + public override async Task Day(bool async) + { + await AssertTranslationFailed(() => base.Day(async)); + + AssertSql(); + } + + public override async Task Hour(bool async) + { + await AssertTranslationFailed(() => base.Hour(async)); + + AssertSql(); + } + + public override async Task Minute(bool async) + { + await AssertTranslationFailed(() => base.Minute(async)); + + AssertSql(); + } + + public override async Task Second(bool async) + { + await AssertTranslationFailed(() => base.Second(async)); + + AssertSql(); + } + + public override async Task Millisecond(bool async) + { + await AssertTranslationFailed(() => base.Millisecond(async)); + + AssertSql(); + } + + public override async Task Microsecond(bool async) + { + await AssertTranslationFailed(() => base.Microsecond(async)); + + AssertSql(); + } + + public override async Task Nanosecond(bool async) + { + await AssertTranslationFailed(() => base.Nanosecond(async)); + + AssertSql(); + } + + public override async Task TimeOfDay(bool async) + { + await base.TimeOfDay(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddYears(bool async) + { + await base.AddYears(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddMonths(bool async) + { + await base.AddMonths(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddDays(bool async) + { + await base.AddDays(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddHours(bool async) + { + await base.AddHours(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddMinutes(bool async) + { + await base.AddMinutes(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddSeconds(bool async) + { + await base.AddSeconds(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override async Task AddMilliseconds(bool async) + { + await base.AddMilliseconds(async); + + AssertSql( + """ +SELECT "b"."DateTimeOffset" +FROM "BasicTypesEntities" AS "b" +"""); + } + + public override Task ToUnixTimeMilliseconds(bool async) + => AssertTranslationFailed(() => base.ToUnixTimeMilliseconds(async)); + + public override Task ToUnixTimeSecond(bool async) + => AssertTranslationFailed(() => base.ToUnixTimeSecond(async)); + + public override async Task Milliseconds_parameter_and_constant(bool async) + { + await base.Milliseconds_parameter_and_constant(async); + + AssertSql( + """ +SELECT COUNT(*) +FROM "BasicTypesEntities" AS "b" +WHERE "b"."DateTimeOffset" = '1902-01-02 10:00:00.1234567+01:30' +"""); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsSqliteTest.cs new file mode 100644 index 00000000000..a40f0cff822 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/DateTimeTranslationsSqliteTest.cs @@ -0,0 +1,250 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class DateTimeTranslationsSqliteTest : DateTimeTranslationsTestBase +{ + public DateTimeTranslationsSqliteTest(BasicTypesQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Now(bool async) + { + await base.Now(async); + + AssertSql( + """ +@myDatetime='2015-04-10T00:00:00.0000000' (DbType = DateTime) + +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 rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime'), '0'), '.') <> @myDatetime +"""); + } + + public override async Task UtcNow(bool async) + { + await base.UtcNow(async); + + AssertSql( + """ +@myDatetime='2015-04-10T00:00:00.0000000' (DbType = DateTime) + +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 rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', 'now'), '0'), '.') <> @myDatetime +"""); + } + + public override async Task Today(bool async) + { + await base.Today(async); + + AssertSql( + """ +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"."DateTime" = rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime', 'start of day'), '0'), '.') +"""); + } + + public override async Task Date(bool async) + { + await base.Date(async); + + AssertSql( + """ +@myDatetime='1998-05-04T00:00:00.0000000' (DbType = DateTime) + +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 rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', "b"."DateTime", 'start of day'), '0'), '.') = @myDatetime +"""); + } + + public override async Task AddYear(bool async) + { + await base.AddYear(async); + + AssertSql( + """ +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(strftime('%Y', "b"."DateTime", CAST(1 AS TEXT) || ' years') AS INTEGER) = 1999 +"""); + } + + public override async Task Year(bool async) + { + await base.Year(async); + + AssertSql( + """ +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(strftime('%Y', "b"."DateTime") AS INTEGER) = 1998 +"""); + } + + public override async Task Month(bool async) + { + await base.Month(async); + + AssertSql( + """ +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(strftime('%m', "b"."DateTime") AS INTEGER) = 5 +"""); + } + + public override async Task DayOfYear(bool async) + { + await base.DayOfYear(async); + + AssertSql( + """ +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(strftime('%j', "b"."DateTime") AS INTEGER) = 124 +"""); + } + + public override async Task Day(bool async) + { + await base.Day(async); + + AssertSql( + """ +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(strftime('%d', "b"."DateTime") AS INTEGER) = 4 +"""); + } + + public override async Task Hour(bool async) + { + await base.Hour(async); + + AssertSql( + """ +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(strftime('%H', "b"."DateTime") AS INTEGER) = 15 +"""); + } + + public override async Task Minute(bool async) + { + await base.Minute(async); + + AssertSql( + """ +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(strftime('%M', "b"."DateTime") AS INTEGER) = 30 +"""); + } + + public override async Task Second(bool async) + { + await base.Second(async); + + AssertSql( + """ +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(strftime('%S', "b"."DateTime") AS INTEGER) = 10 +"""); + } + + public override async Task Millisecond(bool async) + { + await base.Millisecond(async); + + AssertSql( + """ +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(strftime('%f', "b"."DateTime") AS REAL) * 1000.0) % 1000.0 = 123.0 +"""); + } + + public override async Task TimeOfDay(bool async) + { + await base.TimeOfDay(async); + + AssertSql( + """ +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 rtrim(rtrim(strftime('%H:%M:%f', "b"."DateTime"), '0'), '.') = '00:00:00' +"""); + } + + public override Task subtract_and_TotalDays(bool async) + => AssertTranslationFailed(() => base.subtract_and_TotalDays(async)); + + public override async Task Parse_with_constant(bool async) + { + await base.Parse_with_constant(async); + + AssertSql( + """ +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"."DateTime" = '1998-05-04 15:30:10' +"""); + } + + public override async Task Parse_with_parameter(bool async) + { + await base.Parse_with_parameter(async); + + AssertSql( + """ +@Parse='1998-05-04T15:30:10.0000000' (DbType = DateTime) + +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"."DateTime" = @Parse +"""); + } + + public override async Task New_with_constant(bool async) + { + await base.New_with_constant(async); + + AssertSql( + """ +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"."DateTime" = '1998-05-04 15:30:10' +"""); + } + + public override async Task New_with_parameters(bool async) + { + await base.New_with_parameters(async); + + AssertSql( + """ +@p='1998-05-04T15:30:10.0000000' (DbType = DateTime) + +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"."DateTime" = @p +"""); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqliteTest.cs new file mode 100644 index 00000000000..eee73054212 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/TimeOnlyTranslationsSqliteTest.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class TimeOnlyTranslationsSqliteTest : TimeOnlyTranslationsTestBase +{ + public TimeOnlyTranslationsSqliteTest(BasicTypesQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + public override async Task Hour(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Hour(async)); + + AssertSql(); + } + + public override async Task Minute(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Minute(async)); + + AssertSql(); + } + + public override async Task Second(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Second(async)); + + AssertSql(); + } + + public override async Task Millisecond(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Millisecond(async)); + + AssertSql(); + } + + public override async Task Microsecond(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Microsecond(async)); + + AssertSql(); + } + + public override async Task Nanosecond(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Nanosecond(async)); + + AssertSql(); + } + + public override async Task AddHours(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.AddHours(async)); + + AssertSql(); + } + + public override async Task AddMinutes(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.AddMinutes(async)); + + AssertSql(); + } + + public override async Task Add_TimeSpan(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Add_TimeSpan(async)); + + AssertSql(); + } + + public override async Task IsBetween(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.IsBetween(async)); + + AssertSql(); + } + + public override async Task Subtract(bool async) + { + // TimeSpan. Issue #18844. + await AssertTranslationFailed(() => base.Subtract(async)); + + AssertSql(); + } + + public override async Task FromDateTime_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.FromDateTime_compared_to_property(async)); + + AssertSql(); + } + + public override async Task FromDateTime_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.FromDateTime_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task FromDateTime_compared_to_constant(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.FromDateTime_compared_to_constant(async)); + + AssertSql(); + } + + public override async Task FromTimeSpan_compared_to_property(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.FromTimeSpan_compared_to_property(async)); + + AssertSql(); + } + + public override async Task FromTimeSpan_compared_to_parameter(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.FromTimeSpan_compared_to_parameter(async)); + + AssertSql(); + } + + public override async Task Order_by_FromTimeSpan(bool async) + { + // TimeOnly/DateOnly is not supported. Issue #25103. + await AssertTranslationFailed(() => base.Order_by_FromTimeSpan(async)); + + AssertSql(); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsSqliteTest.cs new file mode 100644 index 00000000000..3f49f84f9cb --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/Temporal/TimeSpanTranslationsSqliteTest.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query.Translations.Temporal; + +public class TimeSpanTranslationsSqliteTest : TimeSpanTranslationsTestBase +{ + public TimeSpanTranslationsSqliteTest(BasicTypesQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) + : base(fixture) + { + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + // Translate TimeSpan members, #18844 + public override async Task Hours(bool async) + { + await AssertTranslationFailed(() => base.Hours(async)); + + AssertSql(); + } + + // Translate TimeSpan members, #18844 + public override async Task Minutes(bool async) + { + await AssertTranslationFailed(() => base.Minutes(async)); + + AssertSql(); + } + + public override async Task Seconds(bool async) + { + await AssertTranslationFailed(() => base.Seconds(async)); + + AssertSql(); + } + + // Translate TimeSpan members, #18844 + public override async Task Milliseconds(bool async) + { + await AssertTranslationFailed(() => base.Milliseconds(async)); + + AssertSql(); + } + + // Translate TimeSpan members, #18844 + public override async Task Microseconds(bool async) + { + await AssertTranslationFailed(() => base.Microseconds(async)); + + AssertSql(); + } + + // Translate TimeSpan members, #18844 + public override async Task Nanoseconds(bool async) + { + await AssertTranslationFailed(() => base.Nanoseconds(async)); + + AssertSql(); + } + + [ConditionalFact] + public virtual void Check_all_tests_overridden() + => TestHelpers.AssertAllMethodsOverridden(GetType()); + + private void AssertSql(params string[] expected) + => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/TemporalTranslationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/Translations/TemporalTranslationsSqliteTest.cs deleted file mode 100644 index 06a8c6cb035..00000000000 --- a/test/EFCore.Sqlite.FunctionalTests/Query/Translations/TemporalTranslationsSqliteTest.cs +++ /dev/null @@ -1,853 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.EntityFrameworkCore.TestModels.BasicTypesModel; - -namespace Microsoft.EntityFrameworkCore.Query.Translations; - -public class TemporalTranslationsSqliteTest : TemporalTranslationsTestBase -{ - public TemporalTranslationsSqliteTest(BasicTypesQuerySqliteFixture fixture, ITestOutputHelper testOutputHelper) - : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } - - #region DateTime - - public override async Task DateTime_Now(bool async) - { - await base.DateTime_Now(async); - - AssertSql( - """ -@myDatetime='2015-04-10T00:00:00.0000000' (DbType = DateTime) - -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 rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime'), '0'), '.') <> @myDatetime -"""); - } - - public override async Task DateTime_UtcNow(bool async) - { - await base.DateTime_UtcNow(async); - - AssertSql( - """ -@myDatetime='2015-04-10T00:00:00.0000000' (DbType = DateTime) - -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 rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', 'now'), '0'), '.') <> @myDatetime -"""); - } - - public override async Task DateTime_Today(bool async) - { - await base.DateTime_Today(async); - - AssertSql( - """ -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"."DateTime" = rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime', 'start of day'), '0'), '.') -"""); - } - - public override async Task DateTime_Date(bool async) - { - await base.DateTime_Date(async); - - AssertSql( - """ -@myDatetime='1998-05-04T00:00:00.0000000' (DbType = DateTime) - -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 rtrim(rtrim(strftime('%Y-%m-%d %H:%M:%f', "b"."DateTime", 'start of day'), '0'), '.') = @myDatetime -"""); - } - - public override async Task DateTime_AddYear(bool async) - { - await base.DateTime_AddYear(async); - - AssertSql( - """ -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(strftime('%Y', "b"."DateTime", CAST(1 AS TEXT) || ' years') AS INTEGER) = 1999 -"""); - } - - public override async Task DateTime_Year(bool async) - { - await base.DateTime_Year(async); - - AssertSql( - """ -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(strftime('%Y', "b"."DateTime") AS INTEGER) = 1998 -"""); - } - - public override async Task DateTime_Month(bool async) - { - await base.DateTime_Month(async); - - AssertSql( - """ -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(strftime('%m', "b"."DateTime") AS INTEGER) = 5 -"""); - } - - public override async Task DateTime_DayOfYear(bool async) - { - await base.DateTime_DayOfYear(async); - - AssertSql( - """ -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(strftime('%j', "b"."DateTime") AS INTEGER) = 124 -"""); - } - - public override async Task DateTime_Day(bool async) - { - await base.DateTime_Day(async); - - AssertSql( - """ -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(strftime('%d', "b"."DateTime") AS INTEGER) = 4 -"""); - } - - public override async Task DateTime_Hour(bool async) - { - await base.DateTime_Hour(async); - - AssertSql( - """ -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(strftime('%H', "b"."DateTime") AS INTEGER) = 15 -"""); - } - - public override async Task DateTime_Minute(bool async) - { - await base.DateTime_Minute(async); - - AssertSql( - """ -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(strftime('%M', "b"."DateTime") AS INTEGER) = 30 -"""); - } - - public override async Task DateTime_Second(bool async) - { - await base.DateTime_Second(async); - - AssertSql( - """ -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(strftime('%S', "b"."DateTime") AS INTEGER) = 10 -"""); - } - - public override async Task DateTime_Millisecond(bool async) - { - await base.DateTime_Millisecond(async); - - AssertSql( - """ -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(strftime('%f', "b"."DateTime") AS REAL) * 1000.0) % 1000.0 = 123.0 -"""); - } - - public override async Task DateTime_TimeOfDay(bool async) - { - await base.DateTime_TimeOfDay(async); - - AssertSql( - """ -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 rtrim(rtrim(strftime('%H:%M:%f', "b"."DateTime"), '0'), '.') = '00:00:00' -"""); - } - - public override Task DateTime_subtract_and_TotalDays(bool async) - => AssertTranslationFailed(() => base.DateTime_subtract_and_TotalDays(async)); - - public override async Task DateTime_Parse_with_constant(bool async) - { - await base.DateTime_Parse_with_constant(async); - - AssertSql( - """ -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"."DateTime" = '1998-05-04 15:30:10' -"""); - } - - public override async Task DateTime_Parse_with_parameter(bool async) - { - await base.DateTime_Parse_with_parameter(async); - - AssertSql( - """ -@Parse='1998-05-04T15:30:10.0000000' (DbType = DateTime) - -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"."DateTime" = @Parse -"""); - } - - public override async Task DateTime_new_with_constant(bool async) - { - await base.DateTime_new_with_constant(async); - - AssertSql( - """ -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"."DateTime" = '1998-05-04 15:30:10' -"""); - } - - public override async Task DateTime_new_with_parameters(bool async) - { - await base.DateTime_new_with_parameters(async); - - AssertSql( - """ -@p='1998-05-04T15:30:10.0000000' (DbType = DateTime) - -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"."DateTime" = @p -"""); - } - - #endregion DateTime - - #region DateOnly - - public override async Task DateOnly_Year(bool async) - { - await base.DateOnly_Year(async); - - AssertSql( - """ -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(strftime('%Y', "b"."DateOnly") AS INTEGER) = 1990 -"""); - } - - public override async Task DateOnly_Month(bool async) - { - await base.DateOnly_Month(async); - - AssertSql( - """ -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(strftime('%m', "b"."DateOnly") AS INTEGER) = 11 -"""); - } - - public override async Task DateOnly_Day(bool async) - { - await base.DateOnly_Day(async); - - AssertSql( - """ -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(strftime('%d', "b"."DateOnly") AS INTEGER) = 10 -"""); - } - - public override async Task DateOnly_DayOfYear(bool async) - { - await base.DateOnly_DayOfYear(async); - - AssertSql( - """ -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(strftime('%j', "b"."DateOnly") AS INTEGER) = 314 -"""); - } - - public override async Task DateOnly_DayOfWeek(bool async) - { - await base.DateOnly_DayOfWeek(async); - - AssertSql( - """ -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(strftime('%w', "b"."DateOnly") AS INTEGER) = 6 -"""); - } - - public override async Task DateOnly_AddYears(bool async) - { - await base.DateOnly_AddYears(async); - - AssertSql( - """ -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 date("b"."DateOnly", CAST(3 AS TEXT) || ' years') = '1993-11-10' -"""); - } - - public override async Task DateOnly_AddMonths(bool async) - { - await base.DateOnly_AddMonths(async); - - AssertSql( - """ -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 date("b"."DateOnly", CAST(3 AS TEXT) || ' months') = '1991-02-10' -"""); - } - - public override async Task DateOnly_AddDays(bool async) - { - await base.DateOnly_AddDays(async); - - AssertSql( - """ -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 date("b"."DateOnly", CAST(3 AS TEXT) || ' days') = '1990-11-13' -"""); - } - - public override async Task DateOnly_FromDateTime(bool async) - { - await base.DateOnly_FromDateTime(async); - - AssertSql( - """ -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 date("b"."DateTime") = '1998-05-04' -"""); - } - - public override async Task DateOnly_FromDateTime_compared_to_property(bool async) - { - await base.DateOnly_FromDateTime_compared_to_property(async); - - AssertSql( - """ -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 date("b"."DateTime") = "b"."DateOnly" -"""); - } - - public override async Task DateOnly_FromDateTime_compared_to_constant_and_parameter(bool async) - { - await base.DateOnly_FromDateTime_compared_to_constant_and_parameter(async); - - AssertSql( - """ -@dateOnly='10/11/0002' (DbType = Date) - -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 date("b"."DateTime") IN (@dateOnly, '1998-05-04') -"""); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_DateOnly_AddYears_Year(bool async) - { - await AssertQuery( - async, - ss => ss.Set().Where(m => m.DateOnly.AddYears(3).Year == 1993)); - - AssertSql( - """ -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(strftime('%Y', "b"."DateOnly", CAST(3 AS TEXT) || ' years') AS INTEGER) = 1993 -"""); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_DateOnly_AddYears_AddMonths(bool async) - { - await AssertQuery( - async, - ss => ss.Set().Where(m => m.DateOnly.AddYears(3).AddMonths(3) == new DateOnly(1994, 2, 10))); - - AssertSql( - """ -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 date("b"."DateOnly", CAST(3 AS TEXT) || ' years', CAST(3 AS TEXT) || ' months') = '1994-02-10' -"""); - } - - public override async Task DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_property_DateOnly_with_constant_TimeOnly(async)); - - AssertSql(); - } - - public override async Task DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_property_DateOnly_with_property_TimeOnly(async)); - - AssertSql(); - } - - public override async Task DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_constant_DateTime_with_property_TimeOnly(async)); - - AssertSql(); - } - - public override async Task DateOnly_ToDateTime_with_complex_DateTime(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_with_complex_DateTime(async)); - - AssertSql(); - } - - public override async Task DateOnly_ToDateTime_with_complex_TimeOnly(bool async) - { - await AssertTranslationFailed(() => base.DateOnly_ToDateTime_with_complex_TimeOnly(async)); - - AssertSql(); - } - - #endregion DateOnly - - #region TimeOnly - - public override async Task TimeOnly_Hour(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Hour(async)); - - AssertSql(); - } - - public override async Task TimeOnly_Minute(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Minute(async)); - - AssertSql(); - } - - public override async Task TimeOnly_Second(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Second(async)); - - AssertSql(); - } - - public override async Task TimeOnly_Millisecond(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Millisecond(async)); - - AssertSql(); - } - - public override async Task TimeOnly_Microsecond(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Microsecond(async)); - - AssertSql(); - } - - public override async Task TimeOnly_Nanosecond(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Nanosecond(async)); - - AssertSql(); - } - - public override async Task TimeOnly_AddHours(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_AddHours(async)); - - AssertSql(); - } - - public override async Task TimeOnly_AddMinutes(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_AddMinutes(async)); - - AssertSql(); - } - - public override async Task TimeOnly_Add_TimeSpan(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_Add_TimeSpan(async)); - - AssertSql(); - } - - public override async Task TimeOnly_IsBetween(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_IsBetween(async)); - - AssertSql(); - } - - public override async Task TimeOnly_subtract_TimeOnly(bool async) - { - // TimeSpan. Issue #18844. - await AssertTranslationFailed(() => base.TimeOnly_subtract_TimeOnly(async)); - - AssertSql(); - } - - public override async Task TimeOnly_FromDateTime_compared_to_property(bool async) - { - // TimeOnly/DateOnly is not supported. Issue #25103. - await AssertTranslationFailed(() => base.TimeOnly_FromDateTime_compared_to_property(async)); - - AssertSql(); - } - - public override async Task TimeOnly_FromDateTime_compared_to_parameter(bool async) - { - // TimeOnly/DateOnly is not supported. Issue #25103. - await AssertTranslationFailed(() => base.TimeOnly_FromDateTime_compared_to_parameter(async)); - - AssertSql(); - } - - public override async Task TimeOnly_FromDateTime_compared_to_constant(bool async) - { - // TimeOnly/DateOnly is not supported. Issue #25103. - await AssertTranslationFailed(() => base.TimeOnly_FromDateTime_compared_to_constant(async)); - - AssertSql(); - } - - public override async Task TimeOnly_FromTimeSpan_compared_to_property(bool async) - { - // TimeOnly/DateOnly is not supported. Issue #25103. - await AssertTranslationFailed(() => base.TimeOnly_FromTimeSpan_compared_to_property(async)); - - AssertSql(); - } - - public override async Task TimeOnly_FromTimeSpan_compared_to_parameter(bool async) - { - // TimeOnly/DateOnly is not supported. Issue #25103. - await AssertTranslationFailed(() => base.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(); - } - - #endregion TimeOnly - - #region DateTimeOffset - - public override async Task DateTimeOffset_Now(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Now(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_UtcNow(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_UtcNow(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Date(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Date(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Year(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Year(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Month(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Month(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_DayOfYear(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_DayOfYear(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Day(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Day(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Hour(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Hour(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Minute(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Minute(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Second(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Second(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Millisecond(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Millisecond(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Microsecond(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Microsecond(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_Nanosecond(bool async) - { - await AssertTranslationFailed(() => base.DateTimeOffset_Nanosecond(async)); - - AssertSql(); - } - - public override async Task DateTimeOffset_TimeOfDay(bool async) - { - await base.DateTimeOffset_TimeOfDay(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddYears(bool async) - { - await base.DateTimeOffset_AddYears(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddMonths(bool async) - { - await base.DateTimeOffset_AddMonths(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddDays(bool async) - { - await base.DateTimeOffset_AddDays(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddHours(bool async) - { - await base.DateTimeOffset_AddHours(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddMinutes(bool async) - { - await base.DateTimeOffset_AddMinutes(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddSeconds(bool async) - { - await base.DateTimeOffset_AddSeconds(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override async Task DateTimeOffset_AddMilliseconds(bool async) - { - await base.DateTimeOffset_AddMilliseconds(async); - - AssertSql( - """ -SELECT "b"."DateTimeOffset" -FROM "BasicTypesEntities" AS "b" -"""); - } - - public override Task DateTimeOffset_ToUnixTimeMilliseconds(bool async) - => AssertTranslationFailed(() => base.DateTimeOffset_ToUnixTimeMilliseconds(async)); - - public override Task DateTimeOffset_ToUnixTimeSecond(bool async) - => AssertTranslationFailed(() => base.DateTimeOffset_ToUnixTimeSecond(async)); - - public override async Task DateTimeOffset_milliseconds_parameter_and_constant(bool async) - { - await base.DateTimeOffset_milliseconds_parameter_and_constant(async); - - AssertSql( - """ -SELECT COUNT(*) -FROM "BasicTypesEntities" AS "b" -WHERE "b"."DateTimeOffset" = '1902-01-02 10:00:00.1234567+01:30' -"""); - } - - #endregion DateTimeOffset - - #region TimeSpan - - // Translate TimeSpan members, #18844 - public override async Task TimeSpan_Hours(bool async) - { - await AssertTranslationFailed(() => base.TimeSpan_Hours(async)); - - AssertSql(); - } - - // Translate TimeSpan members, #18844 - public override async Task TimeSpan_Minutes(bool async) - { - await AssertTranslationFailed(() => base.TimeSpan_Minutes(async)); - - AssertSql(); - } - - public override async Task TimeSpan_Seconds(bool async) - { - await AssertTranslationFailed(() => base.TimeSpan_Seconds(async)); - - AssertSql(); - } - - // Translate TimeSpan members, #18844 - public override async Task TimeSpan_Milliseconds(bool async) - { - await AssertTranslationFailed(() => base.TimeSpan_Milliseconds(async)); - - AssertSql(); - } - - // Translate TimeSpan members, #18844 - public override async Task TimeSpan_Microseconds(bool async) - { - await AssertTranslationFailed(() => base.TimeSpan_Microseconds(async)); - - AssertSql(); - } - - // Translate TimeSpan members, #18844 - public override async Task TimeSpan_Nanoseconds(bool async) - { - await AssertTranslationFailed(() => base.TimeSpan_Nanoseconds(async)); - - AssertSql(); - } - - #endregion TimeSpan - - [ConditionalFact] - public virtual void Check_all_tests_overridden() - => TestHelpers.AssertAllMethodsOverridden(GetType()); - - private void AssertSql(params string[] expected) - => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); -}