/// <summary> /// Binds time related functions to create a LINQ <see cref="Expression"/>. /// </summary> /// <param name="node">The query node to bind.</param> /// <param name="context">The query binder context.</param> /// <returns>The LINQ <see cref="Expression"/> created.</returns> protected virtual Expression BindTimeRelatedProperty(SingleValueFunctionCallNode node, QueryBinderContext context) { CheckArgumentNull(node, context); Expression[] arguments = BindArguments(node.Parameters, context); Contract.Assert(arguments.Length == 1 && ExpressionBinderHelper.IsTimeRelated(arguments[0].Type)); // We should support DateTime & DateTimeOffset even though DateTime is not part of OData v4 Spec. Expression parameter = arguments[0]; PropertyInfo property; if (ExpressionBinderHelper.IsTimeOfDay(parameter.Type)) { Contract.Assert(ClrCanonicalFunctions.TimeOfDayProperties.ContainsKey(node.Name)); property = ClrCanonicalFunctions.TimeOfDayProperties[node.Name]; } #if NET6_0 else if (parameter.Type.IsTimeOnly()) { Contract.Assert(ClrCanonicalFunctions.TimeOnlyProperties.ContainsKey(node.Name)); property = ClrCanonicalFunctions.TimeOnlyProperties[node.Name]; } #endif else if (ExpressionBinderHelper.IsDateTime(parameter.Type)) { Contract.Assert(ClrCanonicalFunctions.DateTimeProperties.ContainsKey(node.Name)); property = ClrCanonicalFunctions.DateTimeProperties[node.Name]; } else if (ExpressionBinderHelper.IsTimeSpan(parameter.Type)) { Contract.Assert(ClrCanonicalFunctions.TimeSpanProperties.ContainsKey(node.Name)); property = ClrCanonicalFunctions.TimeSpanProperties[node.Name]; } else { Contract.Assert(ClrCanonicalFunctions.DateTimeOffsetProperties.ContainsKey(node.Name)); property = ClrCanonicalFunctions.DateTimeOffsetProperties[node.Name]; } return(ExpressionBinderHelper.MakeFunctionCall(property, context.QuerySettings, parameter)); }
/// <summary> /// Binds 'fractionalseconds' function to create a LINQ <see cref="Expression"/>. /// </summary> /// <param name="node">The query node to bind.</param> /// <param name="context">The query binder context.</param> /// <returns>The LINQ <see cref="Expression"/> created.</returns> protected virtual Expression BindFractionalSeconds(SingleValueFunctionCallNode node, QueryBinderContext context) { CheckArgumentNull(node, context, "fractionalseconds"); Expression[] arguments = BindArguments(node.Parameters, context); Contract.Assert(arguments.Length == 1 && (ExpressionBinderHelper.IsTimeRelated(arguments[0].Type))); // We should support DateTime & DateTimeOffset even though DateTime is not part of OData v4 Spec. Expression parameter = arguments[0]; PropertyInfo property; if (ExpressionBinderHelper.IsTimeOfDay(parameter.Type)) { property = ClrCanonicalFunctions.TimeOfDayProperties[ClrCanonicalFunctions.MillisecondFunctionName]; } else if (ExpressionBinderHelper.IsDateTime(parameter.Type)) { property = ClrCanonicalFunctions.DateTimeProperties[ClrCanonicalFunctions.MillisecondFunctionName]; } else if (ExpressionBinderHelper.IsTimeSpan(parameter.Type)) { property = ClrCanonicalFunctions.TimeSpanProperties[ClrCanonicalFunctions.MillisecondFunctionName]; } else { property = ClrCanonicalFunctions.DateTimeOffsetProperties[ClrCanonicalFunctions.MillisecondFunctionName]; } // Millisecond Expression milliSecond = ExpressionBinderHelper.MakePropertyAccess(property, parameter, context.QuerySettings); Expression decimalMilliSecond = Expression.Convert(milliSecond, typeof(decimal)); Expression fractionalSeconds = Expression.Divide(decimalMilliSecond, Expression.Constant(1000m, typeof(decimal))); return(ExpressionBinderHelper.CreateFunctionCallWithNullPropagation(fractionalSeconds, arguments, context.QuerySettings)); }