/// <summary>Creates a custom method definition from it's label.</summary> /// <param name="customMethodLabel">The label to call the custom method definition.</param> /// <returns>The custom method created.</returns> public static AggregationMethodDefinition Custom(string customMethodLabel) { ExceptionUtils.CheckArgumentNotNull(customMethodLabel, "customMethodLabel"); // Custom aggregation methods MUST use a namespace-qualified name (see [OData-ABNF]), i.e. contain at least one dot. Debug.Assert(customMethodLabel.Contains(OData.ExpressionConstants.SymbolDot)); var aggregationMethod = new AggregationMethodDefinition(AggregationMethod.Custom); aggregationMethod.MethodLabel = customMethodLabel; return(aggregationMethod); }
private IEdmTypeReference CreateAggregateExpressionTypeReference(SingleValueNode expression, AggregationMethodDefinition method) { var expressionType = expression.TypeReference; if (expressionType == null && aggregateExpressionsCache != null) { var openProperty = expression as SingleValueOpenPropertyAccessNode; if (openProperty != null) { expressionType = GetTypeReferenceByPropertyName(openProperty.Name); } } switch (method.MethodKind) { case AggregationMethod.Average: var expressionPrimitiveKind = expressionType.PrimitiveKind(); switch (expressionPrimitiveKind) { case EdmPrimitiveTypeKind.Int32: case EdmPrimitiveTypeKind.Int64: case EdmPrimitiveTypeKind.Double: return(EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Double, expressionType.IsNullable)); case EdmPrimitiveTypeKind.Decimal: return(EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Decimal, expressionType.IsNullable)); default: throw new ODataException( ODataErrorStrings.ApplyBinder_AggregateExpressionIncompatibleTypeForMethod(expression, expressionPrimitiveKind)); } case AggregationMethod.VirtualPropertyCount: case AggregationMethod.CountDistinct: // Issue #758: CountDistinct and $Count should return type Edm.Decimal with Scale="0" and sufficient Precision. return(EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int64, false)); case AggregationMethod.Max: case AggregationMethod.Min: case AggregationMethod.Sum: return(expressionType); default: // Only the EdmModel knows which type the custom aggregation methods returns. // Since we do not have a reference for it, right now we are assuming that all custom aggregation methods returns Doubles // TODO: find a appropriate way of getting the return type. return(EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Double, expressionType.IsNullable)); } }
/// <summary> /// Create a AggregateExpression. /// </summary> /// <param name="expression">The aggregation expression.</param> /// <param name="methodDefinition">The <see cref="AggregationMethodDefinition"/>.</param> /// <param name="alias">The aggregation alias.</param> /// <param name="typeReference">The <see cref="IEdmTypeReference"/> of this aggregate expression.</param> public AggregateExpression(SingleValueNode expression, AggregationMethodDefinition methodDefinition, string alias, IEdmTypeReference typeReference) : this(expression, methodDefinition.MethodKind, alias, typeReference) { this.methodDefinition = methodDefinition; }