diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerFromPartsFunctionTranslator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerFromPartsFunctionTranslator.cs index 449aa3048a0..b6fd080e5cc 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerFromPartsFunctionTranslator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerFromPartsFunctionTranslator.cs @@ -14,26 +14,46 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal { public class SqlServerFromPartsFunctionTranslator : IMethodCallTranslator { - private readonly ISqlExpressionFactory _sqlExpressionFactory; - private readonly IRelationalTypeMappingSource _typeMappingSource; - private static readonly MethodInfo _dateFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions) - .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int) }); + .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateFromParts), + new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int) }); private static readonly MethodInfo _dateTimeFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions) - .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTimeFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTimeFromParts), + new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); private static readonly MethodInfo _dateTime2FromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions) - .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTime2FromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTime2FromParts), + new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), + typeof(int), typeof(int), typeof(int) }); private static readonly MethodInfo _dateTimeOffsetFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions) - .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTimeOffsetFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.DateTimeOffsetFromParts), + new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), + typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); private static readonly MethodInfo _smallDateTimeFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions) - .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.SmallDateTimeFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.SmallDateTimeFromParts), + new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); private static readonly MethodInfo _timeFromPartsMethodInfo = typeof(SqlServerDbFunctionsExtensions) - .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.TimeFromParts), new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + .GetRuntimeMethod(nameof(SqlServerDbFunctionsExtensions.TimeFromParts), + new[] { typeof(DbFunctions), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + + private static readonly IDictionary _methodFunctionMapping + = new Dictionary + { + { _dateFromPartsMethodInfo, ("DATEFROMPARTS", "date") }, + { _dateTimeFromPartsMethodInfo, ("DATETIMEFROMPARTS", "datetime") }, + { _dateTime2FromPartsMethodInfo, ("DATETIME2FROMPARTS", "datetime2") }, + { _dateTimeOffsetFromPartsMethodInfo, ("DATETIMEOFFSETFROMPARTS", "datetimeoffset") }, + { _smallDateTimeFromPartsMethodInfo, ("SMALLDATETIMEFROMPARTS", "smalldatetime") }, + { _timeFromPartsMethodInfo, ("TIMEFROMPARTS", "time") }, + }; + + private readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly IRelationalTypeMappingSource _typeMappingSource; + public SqlServerFromPartsFunctionTranslator( [NotNull] ISqlExpressionFactory sqlExpressionFactory, @@ -45,70 +65,15 @@ public SqlServerFromPartsFunctionTranslator( public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList arguments) { - if (_dateFromPartsMethodInfo.Equals(method)) + if (_methodFunctionMapping.TryGetValue(method, out var value)) { return _sqlExpressionFactory.Function( - "DATEFROMPARTS", + value.FunctionName, arguments.Skip(1), nullResultAllowed: true, argumentsPropagateNullability: arguments.Skip(1).Select(a => true), _dateFromPartsMethodInfo.ReturnType, - _typeMappingSource.FindMapping(typeof(DateTime), "date")); - } - - if (_dateTimeFromPartsMethodInfo.Equals(method)) - { - return _sqlExpressionFactory.Function( - "DATETIMEFROMPARTS", - arguments.Skip(1), - nullResultAllowed: true, - argumentsPropagateNullability: arguments.Skip(1).Select(a => true), - _dateTimeFromPartsMethodInfo.ReturnType, - _typeMappingSource.FindMapping(typeof(DateTime), "datetime")); - } - - if (_dateTime2FromPartsMethodInfo.Equals(method)) - { - return _sqlExpressionFactory.Function( - "DATETIME2FROMPARTS", - arguments.Skip(1), - nullResultAllowed: true, - argumentsPropagateNullability: arguments.Skip(1).Select(a => true), - _dateTime2FromPartsMethodInfo.ReturnType, - _typeMappingSource.FindMapping(typeof(DateTime), "datetime2")); - } - - if (_dateTimeOffsetFromPartsMethodInfo.Equals(method)) - { - return _sqlExpressionFactory.Function( - "DATETIMEOFFSETFROMPARTS", - arguments.Skip(1), - nullResultAllowed: true, - argumentsPropagateNullability: arguments.Skip(1).Select(a => true), - _dateTimeOffsetFromPartsMethodInfo.ReturnType, - _typeMappingSource.FindMapping(typeof(DateTimeOffset), "datetimeoffset")); - } - - if (_smallDateTimeFromPartsMethodInfo.Equals(method)) - { - return _sqlExpressionFactory.Function( - "SMALLDATETIMEFROMPARTS", - arguments.Skip(1), - nullResultAllowed: true, - argumentsPropagateNullability: arguments.Skip(1).Select(a => true), - _smallDateTimeFromPartsMethodInfo.ReturnType, - _typeMappingSource.FindMapping(typeof(DateTime), "smalldatetime")); - } - - if (_timeFromPartsMethodInfo.Equals(method)) - { - return _sqlExpressionFactory.Function( - "TIMEFROMPARTS", - arguments.Skip(1), - nullResultAllowed: true, - argumentsPropagateNullability: arguments.Skip(1).Select(a => true), - _timeFromPartsMethodInfo.ReturnType, - _typeMappingSource.FindMapping(typeof(TimeSpan), "time")); + _typeMappingSource.FindMapping(_dateFromPartsMethodInfo.ReturnType, value.ReturnType)); } return null;