diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMemberTranslator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMemberTranslator.cs index 80786705a11..6aa4c0e51a0 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMemberTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMemberTranslator.cs @@ -60,7 +60,9 @@ public virtual SqlExpression Translate(SqlExpression instance, MemberInfo member "CONVERT", new[] { _sqlExpressionFactory.Fragment("date"), instance }, returnType, - instance.TypeMapping); + declaringType == typeof(DateTime) + ? instance.TypeMapping + : _sqlExpressionFactory.FindMapping(typeof(DateTime))); case nameof(DateTime.TimeOfDay): return _sqlExpressionFactory.Convert(instance, returnType); diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMethodTranslator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMethodTranslator.cs index bc2e39a63d3..a4df834f582 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMethodTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerDateTimeMethodTranslator.cs @@ -45,6 +45,8 @@ public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method if (_methodInfoDatePartMapping.TryGetValue(method, out var datePart)) { + // DateAdd does not accept number argument outside of int range + // AddYears/AddMonths take int argument so no need to check for range return !datePart.Equals("year") && !datePart.Equals("month") && arguments[0] is SqlConstantExpression sqlConstant diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index ec885ef1b58..f8f166c8188 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -7407,6 +7407,17 @@ public virtual void Byte_array_filter_by_length_parameter_compiled() Assert.Equal(2, query(context, byteQueryParam)); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task DateTimeOffset_Date_returns_datetime(bool async) + { + var dateTimeOffset = new DateTimeOffset(2, 3, 1, 8, 0, 0, new TimeSpan(-5, 0, 0)); + + return AssertQuery( + async, + ss => ss.Set().Where(m => m.Timeline.Date >= dateTimeOffset.Date)); + } + protected GearsOfWarContext CreateContext() => Fixture.CreateContext(); protected virtual void ClearLog() diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index c1eeb069199..67aca9e1755 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -7400,6 +7400,18 @@ FROM [Weapons] AS [w] ORDER BY [w0].[IsAutomatic]"); } + public override async Task DateTimeOffset_Date_returns_datetime(bool async) + { + await base.DateTimeOffset_Date_returns_datetime(async); + + AssertSql( + @"@__dateTimeOffset_Date_0='0002-03-01T00:00:00' + +SELECT [m].[Id], [m].[CodeName], [m].[Rating], [m].[Timeline] +FROM [Missions] AS [m] +WHERE CONVERT(date, [m].[Timeline]) >= @__dateTimeOffset_Date_0"); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index ef26bc2722f..9480811a5f8 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -52,6 +52,9 @@ public override Task Where_datetimeoffset_year_component(bool async) public override Task DateTimeOffset_Contains_Less_than_Greater_than(bool async) => AssertTranslationFailed(() => base.DateTimeOffset_Contains_Less_than_Greater_than(async)); + public override Task DateTimeOffset_Date_returns_datetime(bool async) + => AssertTranslationFailed(() => base.DateTimeOffset_Date_returns_datetime(async)); + // Sqlite does not support cross/outer apply public override Task Correlated_collections_inner_subquery_predicate_references_outer_qsre(bool async) => null;