protected override ShapedQueryExpression TranslateCount(ShapedQueryExpression source, LambdaExpression predicate) { var selectExpression = (SelectExpression)source.QueryExpression; if (selectExpression.IsDistinct || selectExpression.Limit != null || selectExpression.Offset != null) { selectExpression.PushdownIntoSubQuery(); } if (predicate != null) { source = TranslateWhere(source, predicate); } var translation = _sqlExpressionFactory.ApplyDefaultTypeMapping( _sqlExpressionFactory.Function("COUNT", new[] { _sqlExpressionFactory.Fragment("*") }, typeof(int))); var _projectionMapping = new Dictionary <ProjectionMember, Expression> { { new ProjectionMember(), translation } }; selectExpression.ClearOrdering(); selectExpression.ReplaceProjection(_projectionMapping); source.ShaperExpression = new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), typeof(int)); return(source); }
protected override ShapedQueryExpression TranslateCount(ShapedQueryExpression source, LambdaExpression predicate) { var selectExpression = (SelectExpression)source.QueryExpression; selectExpression.PrepareForAggregate(); if (predicate != null) { source = TranslateWhere(source, predicate); } var translation = _sqlExpressionFactory.ApplyDefaultTypeMapping( _sqlExpressionFactory.Function("COUNT", new[] { _sqlExpressionFactory.Fragment("*") }, typeof(int))); var projectionMapping = new Dictionary <ProjectionMember, Expression> { { new ProjectionMember(), translation } }; selectExpression.ClearOrdering(); selectExpression.ReplaceProjectionMapping(projectionMapping); source.ShaperExpression = new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), typeof(int)); return(source); }
internal SpannerIntervalExpression(ISqlExpressionFactory sqlExpressionFactory, SqlExpression value, string intervalName) : base(value.Type, value.TypeMapping) { _sqlExpressionFactory = sqlExpressionFactory; _intervalName = intervalName; _value = value; _intervalFragment = _sqlExpressionFactory.Fragment("INTERVAL "); _intervalNameFragment = _sqlExpressionFactory.Fragment($" {_intervalName}"); }
internal SpannerTimestampExtractExpression(ISqlExpressionFactory sqlExpressionFactory, SqlExpression value, string dateTimePartName) : base(value.Type, value.TypeMapping) { _sqlExpressionFactory = sqlExpressionFactory; _dateTimePartName = dateTimePartName; _value = value; _fromFragment = _sqlExpressionFactory.Fragment($"{_dateTimePartName} FROM "); _timezoneFragment = _sqlExpressionFactory.Fragment(" AT TIME ZONE 'UTC'"); }
public virtual SqlExpression TranslateCount([CanBeNull] Expression expression = null) { if (expression != null) { // TODO: Translate Count with predicate for GroupBy return(null); } return(_sqlExpressionFactory.ApplyDefaultTypeMapping( _sqlExpressionFactory.Function("COUNT", new[] { _sqlExpressionFactory.Fragment("*") }, typeof(int)))); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); if (_methodInfoDatePartMapping.TryGetValue(method, out var datePart)) { return(!datePart.Equals("year") && !datePart.Equals("month") && arguments[0] is SqlConstantExpression sqlConstant && ((double)sqlConstant.Value >= int.MaxValue || (double)sqlConstant.Value <= int.MinValue) ? null : _sqlExpressionFactory.Function( "DATEADD", new[] { _sqlExpressionFactory.Fragment(datePart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance }, instance.Type, instance.TypeMapping)); } return(null); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); 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 && ((double)sqlConstant.Value >= int.MaxValue || (double)sqlConstant.Value <= int.MinValue) ? null : _sqlExpressionFactory.Function( "DATEADD", new[] { _sqlExpressionFactory.Fragment(datePart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance }, nullable: true, argumentsPropagateNullability: new[] { false, true, true }, instance.Type, instance.TypeMapping)); } return(null); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); if (_functionMapping.TryGetValue(method, out var functionName)) { var propertyReference = arguments[1]; if (!(propertyReference is ColumnExpression)) { throw new InvalidOperationException(SqlServerStrings.InvalidColumnNameForFreeText); } var typeMapping = propertyReference.TypeMapping; var freeText = _sqlExpressionFactory.ApplyTypeMapping(arguments[2], typeMapping); var functionArguments = new List <SqlExpression> { propertyReference, freeText }; if (arguments.Count == 4) { functionArguments.Add( _sqlExpressionFactory.Fragment($"LANGUAGE {((SqlConstantExpression)arguments[3]).Value}")); } return(_sqlExpressionFactory.Function( functionName, functionArguments, typeof(bool))); } return(null); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { if (_functionMapping.TryGetValue(method, out var functionName)) { var propertyReference = arguments[1]; if (!(propertyReference is ColumnExpression)) { throw new InvalidOperationException("The 'FreeText' method is not supported because the query has switched to client-evaluation. Inspect the log to determine which query expressions are triggering client-evaluation."); } var typeMapping = propertyReference.TypeMapping; var freeText = _sqlExpressionFactory.ApplyTypeMapping(arguments[2], typeMapping); var functionArguments = new List <SqlExpression> { propertyReference, freeText }; if (arguments.Count == 4) { functionArguments.Add( _sqlExpressionFactory.Fragment($"LANGUAGE {((SqlConstantExpression)arguments[3]).Value}")); } return(_sqlExpressionFactory.Function( functionName, functionArguments, typeof(bool))); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression Translate( SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (_methodInfoDateDiffMapping.TryGetValue(method, out var datePart)) { var startDate = arguments[1]; var endDate = arguments[2]; var typeMapping = ExpressionExtensions.InferTypeMapping(startDate, endDate); startDate = _sqlExpressionFactory.ApplyTypeMapping(startDate, typeMapping); endDate = _sqlExpressionFactory.ApplyTypeMapping(endDate, typeMapping); return(_sqlExpressionFactory.Function( "DATEDIFF", new[] { _sqlExpressionFactory.Fragment(datePart), startDate, endDate }, nullable: true, argumentsPropagateNullability: new[] { false, true, true }, typeof(int))); } return(null); }
internal SpannerDateExtractExpression(ISqlExpressionFactory sqlExpressionFactory, SqlExpression value, string dateTimePartName) : base(value.Type, value.TypeMapping) { _sqlExpressionFactory = sqlExpressionFactory; _dateTimePartName = dateTimePartName; _value = value; _fromFragment = _sqlExpressionFactory.Fragment($"{_dateTimePartName} FROM "); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { return(_supportedMethods.Contains(method) ? _sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment(_typeMapping[method.Name]), arguments[0] }, method.ReturnType) : null); }
private IEnumerable <SqlExpression> simplify(IEnumerable <SqlExpression> arguments) { foreach (var argument in arguments) { if (argument is SqlConstantExpression constant && constant.Value is HierarchyId hierarchyId) { yield return(_sqlExpressionFactory.Fragment($"'{hierarchyId}'")); }
public override SqlExpression TranslateLongCount(Expression expression = null) { if (expression != null) { // TODO: Translate Count with predicate for GroupBy return(null); } return(_sqlExpressionFactory.ApplyDefaultTypeMapping( _sqlExpressionFactory.Function("COUNT_BIG", new[] { _sqlExpressionFactory.Fragment("*") }, typeof(long)))); }
/// <inheritdoc /> public virtual SqlExpression Translate( SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (!MethodInfoDatePartMapping.TryGetValue(method, out var datePart)) { return(null); } var interval = arguments[0]; if (instance is null || interval is null) { return(null); } // Note: ideally we'd simply generate a PostgreSQL interval expression, but the .NET mapping of that is TimeSpan, // which does not work for months, years, etc. So we generate special fragments instead. if (interval is SqlConstantExpression constantExpression) { // We generate constant intervals as INTERVAL '1 days' if (constantExpression.Type == typeof(double) && ((double)constantExpression.Value >= int.MaxValue || (double)constantExpression.Value <= int.MinValue)) { return(null); } interval = _sqlExpressionFactory.Fragment(FormattableString.Invariant($"INTERVAL '{constantExpression.Value} {datePart}'")); } else { // For non-constants, we can't parameterize INTERVAL '1 days'. Instead, we use CAST($1 || ' days' AS interval). // Note that a make_interval() function also exists, but accepts only int (for all fields except for // seconds), so we don't use it. // Note: we instantiate SqlBinaryExpression manually rather than via sqlExpressionFactory because // of the non-standard Add expression (concatenate int with text) interval = _sqlExpressionFactory.Convert( new SqlBinaryExpression( ExpressionType.Add, _sqlExpressionFactory.Convert(interval, typeof(string), _textMapping), _sqlExpressionFactory.Constant(' ' + datePart, _textMapping), typeof(string), _textMapping), typeof(TimeSpan), _intervalMapping); } return(_sqlExpressionFactory.Add(instance, interval, instance.TypeMapping)); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); return(_supportedMethods.Contains(method) ? _sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment(_typeMapping[method.Name]), arguments[0] }, nullable: true, argumentsPropagateNullability: new[] { false, true }, method.ReturnType) : null); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { return(method.Name == nameof(ToString) && arguments.Count == 0 && instance != null && _typeMapping.TryGetValue( instance.Type.UnwrapNullableType(), out var storeType) ? _sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment(storeType), instance }, typeof(string)) : null); }
private IEnumerable <SqlExpression> Simplify(IEnumerable <SqlExpression> arguments, bool isGeography) { foreach (var argument in arguments) { if (argument is SqlConstantExpression constant && constant.Value is Geometry geometry && geometry.SRID == (isGeography ? 4326 : 0)) { yield return(_sqlExpressionFactory.Fragment("'" + geometry.AsText() + "'")); continue; } yield return(argument); } }
public virtual SqlExpression Translate(SqlExpression instance, MemberInfo member, Type returnType) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); if (member.DeclaringType == typeof(TimeSpan) && _datePartMappings.TryGetValue(member.Name, out string value)) { return(_sqlExpressionFactory.Function("DATEPART", new [] { _sqlExpressionFactory.Fragment(value), instance }, returnType)); } return(null); }
public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (_methodInfoDatePartMapping.TryGetValue(method, out var datePart) && instance != null) { // DateAdd does not accept number argument outside of int range // AddYears/AddMonths take int argument so no need to check for range if (datePart != "year" && datePart != "month" && arguments[0] is SqlConstantExpression sqlConstant && sqlConstant.Value is double doubleValue && (doubleValue >= int.MaxValue || doubleValue <= int.MinValue)) { return(null); } if (instance is SqlConstantExpression instanceConstant) { instance = instanceConstant.ApplyTypeMapping(_typeMappingSource.FindMapping(typeof(DateTime), "datetime")); } return(_sqlExpressionFactory.Function( "DATEADD", new[] { _sqlExpressionFactory.Fragment(datePart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance }, nullable: true, argumentsPropagateNullability: new[] { false, true, true }, instance.Type, instance.TypeMapping)); } return(null); }
public SqlExpression Translate(SqlExpression instance, MemberInfo member, Type returnType) { if (member.DeclaringType == this._declaringType) { var memberName = member.Name; if (_datePartMapping.TryGetValue(memberName, out var datePart)) { return(_sqlExpressionFactory.Function( "DATEPART", new[] { _sqlExpressionFactory.Fragment(datePart), instance }, returnType)); } } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); return(method.Name == nameof(ToString) && arguments.Count == 0 && instance != null && _typeMapping.TryGetValue(instance.Type, out var storeType) ? _sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment(storeType), instance }, nullable: true, argumentsPropagateNullability: new bool[] { false, true }, typeof(string)) : null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (_functionMapping.TryGetValue(method, out var functionName)) { var propertyReference = arguments[1]; if (!(propertyReference is ColumnExpression)) { throw new InvalidOperationException(SqlServerStrings.InvalidColumnNameForFreeText); } var typeMapping = propertyReference.TypeMapping; var freeText = propertyReference.Type == arguments[2].Type ? _sqlExpressionFactory.ApplyTypeMapping(arguments[2], typeMapping) : _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[2]); var functionArguments = new List <SqlExpression> { propertyReference, freeText }; if (arguments.Count == 4) { functionArguments.Add( _sqlExpressionFactory.Fragment($"LANGUAGE {((SqlConstantExpression)arguments[3]).Value}")); } return(_sqlExpressionFactory.Function( functionName, functionArguments, nullable: true, // TODO: don't propagate for now argumentsPropagateNullability: functionArguments.Select(a => false).ToList(), typeof(bool))); } return(null); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { if (_methodInfoDateDiffMapping.TryGetValue(method, out var datePart)) { var startDate = arguments[1]; var endDate = arguments[2]; var typeMapping = ExpressionExtensions.InferTypeMapping(startDate, endDate); startDate = _sqlExpressionFactory.ApplyTypeMapping(startDate, typeMapping); endDate = _sqlExpressionFactory.ApplyTypeMapping(endDate, typeMapping); return(_sqlExpressionFactory.Function( "DATEDIFF", new[] { _sqlExpressionFactory.Fragment(datePart), startDate, endDate }, typeof(int))); } return(null); }
public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { // Translates parameterless Object.ToString() calls. return(method.Name == nameof(ToString) && arguments.Count == 0 && instance != null && _typeMapping.TryGetValue( instance.Type .UnwrapNullableType(), out var storeType) ? _sqlExpressionFactory.Function( "CONVERT", new[] { instance, _sqlExpressionFactory.Fragment(storeType) }, typeof(string)) : null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression Translate( SqlExpression instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); if (member.DeclaringType == typeof(TimeSpan) && _datePartMappings.TryGetValue(member.Name, out string value)) { return(_sqlExpressionFactory.Function( "DATEPART", new[] { _sqlExpressionFactory.Fragment(value), instance }, nullable: true, argumentsPropagateNullability: new[] { false, true }, returnType)); } return(null); }
private SqlExpression GetFirstArgumentAsInt64(IReadOnlyList <SqlExpression> arguments, long multiplier) { SqlExpression value = _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[0]); if (value.TypeMapping != null && value.TypeMapping.StoreTypeNameBase == "FLOAT64") { value = _sqlExpressionFactory.ApplyDefaultTypeMapping(_sqlExpressionFactory.Function("CAST", new[] { value, _sqlExpressionFactory.Fragment("INT64") }, typeof(long))); } if (multiplier != 1L) { value = _sqlExpressionFactory.Multiply(_sqlExpressionFactory.Constant(multiplier), value, value.TypeMapping); } return(value); }
public virtual SqlExpression Translate(SqlExpression instance, MemberInfo member, Type returnType) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); var declaringType = member.DeclaringType; if (declaringType == typeof(DateTime) || declaringType == typeof(DateTimeOffset)) { var memberName = member.Name; if (_datePartMapping.TryGetValue(memberName, out var datePart)) { return(_sqlExpressionFactory.Function( "DATEPART", new[] { _sqlExpressionFactory.Fragment(datePart), instance }, returnType)); } switch (memberName) { case nameof(DateTime.Date): return(_sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment("date"), instance }, returnType, instance.TypeMapping)); case nameof(DateTime.TimeOfDay): return(_sqlExpressionFactory.Convert(instance, returnType)); case nameof(DateTime.Now): return(_sqlExpressionFactory.Function( declaringType == typeof(DateTime) ? "GETDATE" : "SYSDATETIMEOFFSET", Array.Empty <SqlExpression>(), returnType)); case nameof(DateTime.UtcNow): var serverTranslation = _sqlExpressionFactory.Function( declaringType == typeof(DateTime) ? "GETUTCDATE" : "SYSUTCDATETIME", Array.Empty <SqlExpression>(), returnType); return(declaringType == typeof(DateTime) ? (SqlExpression)serverTranslation : _sqlExpressionFactory.Convert(serverTranslation, returnType)); case nameof(DateTime.Today): return(_sqlExpressionFactory.Function( "CONVERT", new SqlExpression[] { _sqlExpressionFactory.Fragment("date"), _sqlExpressionFactory.Function( "GETDATE", Array.Empty <SqlExpression>(), typeof(DateTime)) }, returnType)); } } return(null); }
public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { if (_methodInfoDateAddMapping != null && _methodInfoDateAddMapping.TryGetValue(method, out var dateAddPart)) { return(arguments[0] is SqlConstantExpression sqlConstant && ((sqlConstant.Value is double && ((double)sqlConstant.Value >= int.MaxValue || (double)sqlConstant.Value <= int.MinValue)) || (sqlConstant.Value is long && ((long)sqlConstant.Value >= int.MaxValue || (long)sqlConstant.Value <= int.MinValue))) ? null : _sqlExpressionFactory.Function( "DATEADD", new[] { _sqlExpressionFactory.Fragment(dateAddPart), _sqlExpressionFactory.Convert(arguments[0], typeof(int)), instance }, instance.Type, instance.TypeMapping)); } else if (_methodInfoDateAddExtensionMapping != null && _methodInfoDateAddExtensionMapping.TryGetValue(method, out var dateAddExtensionPart)) { return(arguments[1] is SqlConstantExpression sqlConstant && ((sqlConstant.Value is double && ((double)sqlConstant.Value >= int.MaxValue || (double)sqlConstant.Value <= int.MinValue)) || (sqlConstant.Value is long && ((long)sqlConstant.Value >= int.MaxValue || (long)sqlConstant.Value <= int.MinValue))) ? null : _sqlExpressionFactory.Function( "DATEADD", new[] { _sqlExpressionFactory.Fragment(dateAddExtensionPart), _sqlExpressionFactory.Convert(arguments[1], typeof(int)), arguments[0] }, arguments[0].Type, arguments[0].TypeMapping)); } else if (_methodInfoDatePartExtensionMapping != null && _methodInfoDatePartExtensionMapping.TryGetValue(method, out var datePart)) { return(_sqlExpressionFactory.Function( "DATEPART", new[] { _sqlExpressionFactory.Fragment(datePart), arguments[0] }, method.ReturnType, null)); } else if (_methodInfoDateDiffMapping != null && _methodInfoDateDiffMapping.TryGetValue(method, out var dateDiffDatePart)) { var startDate = arguments[1]; var endDate = arguments[2]; var typeMapping = ExpressionExtensions.InferTypeMapping(startDate, endDate); startDate = _sqlExpressionFactory.ApplyTypeMapping(startDate, typeMapping); endDate = _sqlExpressionFactory.ApplyTypeMapping(endDate, typeMapping); return(_sqlExpressionFactory.Function( "DATEDIFF", new[] { _sqlExpressionFactory.Fragment(dateDiffDatePart), startDate, endDate }, method.ReturnType, null)); } else if (_methodInfoDateDiffBigMapping != null && _methodInfoDateDiffBigMapping.TryGetValue(method, out var dateDiffBigDatePart)) { var startDate = arguments[1]; var endDate = arguments[2]; var typeMapping = ExpressionExtensions.InferTypeMapping(startDate, endDate); startDate = _sqlExpressionFactory.ApplyTypeMapping(startDate, typeMapping); endDate = _sqlExpressionFactory.ApplyTypeMapping(endDate, typeMapping); return(_sqlExpressionFactory.Function( "DATEDIFF_BIG", new[] { _sqlExpressionFactory.Fragment(dateDiffBigDatePart), startDate, endDate }, method.ReturnType, null)); } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression Translate( SqlExpression instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); var declaringType = member.DeclaringType; if (declaringType == typeof(DateTime) || declaringType == typeof(DateTimeOffset)) { var memberName = member.Name; if (_datePartMapping.TryGetValue(memberName, out var datePart)) { return(_sqlExpressionFactory.Function( "DATEPART", new[] { _sqlExpressionFactory.Fragment(datePart), instance }, nullable: true, argumentsPropagateNullability: new[] { false, true }, returnType)); } switch (memberName) { case nameof(DateTime.Date): return(_sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment("date"), instance }, nullable: true, argumentsPropagateNullability: new[] { false, true }, returnType, declaringType == typeof(DateTime) ? instance.TypeMapping : _typeMappingSource.FindMapping(typeof(DateTime)))); case nameof(DateTime.TimeOfDay): return(_sqlExpressionFactory.Function( "CONVERT", new[] { _sqlExpressionFactory.Fragment("time"), instance }, nullable: true, argumentsPropagateNullability: new[] { false, true }, returnType)); case nameof(DateTime.Now): return(_sqlExpressionFactory.Function( declaringType == typeof(DateTime) ? "GETDATE" : "SYSDATETIMEOFFSET", Array.Empty <SqlExpression>(), nullable: false, argumentsPropagateNullability: Array.Empty <bool>(), returnType)); case nameof(DateTime.UtcNow): var serverTranslation = _sqlExpressionFactory.Function( declaringType == typeof(DateTime) ? "GETUTCDATE" : "SYSUTCDATETIME", Array.Empty <SqlExpression>(), nullable: false, argumentsPropagateNullability: Array.Empty <bool>(), returnType); return(declaringType == typeof(DateTime) ? (SqlExpression)serverTranslation : _sqlExpressionFactory.Convert(serverTranslation, returnType)); case nameof(DateTime.Today): return(_sqlExpressionFactory.Function( "CONVERT", new SqlExpression[] { _sqlExpressionFactory.Fragment("date"), _sqlExpressionFactory.Function( "GETDATE", Array.Empty <SqlExpression>(), nullable: false, argumentsPropagateNullability: Array.Empty <bool>(), typeof(DateTime)) }, nullable: true, argumentsPropagateNullability: new[] { false, true }, returnType)); } } return(null); }