Пример #1
0
        /// <summary>
        /// Get the return value from an aggregate function.
        /// </summary>
        /// <param name="index">Index represents result row number within the grouping, and is used for series functions that return multiple results from one aggregation.</param>
        /// <returns></returns>
        public object ReturnValue(int?index = 0)
        {
            if (ResultMethod != null)
            {
                var      outputsCount = Outputs?.Length ?? 0;
                int      indexAdjust;
                object[] parameters;

                //if the result method has an "index" as the first parameter, then add the index
                if (ResultMethod.GetParameters().Any() && ResultMethod.GetParameters()[0].Name == "index")
                {
                    parameters    = new object[outputsCount + 1];
                    parameters[0] = index;
                    indexAdjust   = 1;
                }
                else
                {
                    parameters  = new object[outputsCount];
                    indexAdjust = 0;
                }

                List <object> arrayValues = null;
                for (var i = 0; i < outputsCount; i++)
                {
                    //FYI: this code will only accommodate for array being last parameter.
                    if (Outputs != null && Outputs[i].IsArray)
                    {
                        if (arrayValues == null)
                        {
                            arrayValues = new List <object>();
                        }
                        arrayValues.Add(null);
                    }
                    else
                    {
                        parameters[i + indexAdjust] = null;
                    }
                }

                if (arrayValues != null)
                {
                    parameters[outputsCount + indexAdjust] = arrayValues.Select(c => Convert.ChangeType(c, Type.GetType("System." + Outputs.Last().DataType)));
                }

                _returnValue = ResultMethod.Invoke(ObjectReference, parameters);

                var arrayNumber = 0;
                for (var i = 0; i < outputsCount; i++)
                {
                    if (Outputs != null && Outputs[i].IsArray)
                    {
                        var array = (object[])parameters[i + indexAdjust];
                        try
                        {
                            Outputs[i].SetValue(arrayNumber >= array.Length ? DBNull.Value : array[arrayNumber]);
                        }
                        catch (Exception ex)
                        {
#if DEBUG
                            throw new AggregateException($"The function {FunctionName} with the output array {Outputs[i].Name} with values {string.Join(",", array)} could not be converted.  " + ex.Message, ex);
#else
                            throw new AggregateException($"The function {FunctionName} with the output array {Outputs[i].Name} could not be converted.  " + ex.Message, ex);
#endif
                        }
                        arrayNumber++;
                    }
                    else
                    {
                        try
                        {
                            Outputs[i].SetValue(parameters[i + indexAdjust]);
                        }
                        catch (Exception ex)
                        {
#if DEBUG
                            throw new AggregateException($"The function {FunctionName} with the output parameter {Outputs[i].Name} with value {parameters[i + indexAdjust]} could not be converted.  " + ex.Message, ex);
#else
                            throw new AggregateException($"The function {FunctionName} with the output parameter {Outputs[i].Name} could not be converted.  " + ex.Message, ex);
#endif
                        }
                    }
                }
            }

            return(_returnValue);
        }
Пример #2
0
        private void Initialize(object target, MethodInfo functionMethod, TableColumn[] inputMappings, TableColumn targetColumn, TableColumn[] outputMappings)
        {
            FunctionMethod = functionMethod;

            var attribute  = functionMethod.GetCustomAttribute <TransformFunctionAttribute>();
            var targetType = target.GetType();

            // Get the ResetMethod/ResultMethod which are used for aggregatate functions.
            if (attribute != null)
            {
                ResetMethod = string.IsNullOrEmpty(attribute.ResetMethod)
                    ? null
                    : targetType.GetMethod(attribute.ResetMethod);

                ResultMethod = string.IsNullOrEmpty(attribute.ResultMethod)
                    ? null
                    : targetType.GetMethod(attribute.ResultMethod);

                ImportMethod = string.IsNullOrEmpty(attribute.ImportMethod)
                            ? null
                            : targetType.GetMethod(attribute.ImportMethod);
            }

            ObjectReference = target;

            TargetColumn = targetColumn;

            ReturnType = GetTypeCode(FunctionMethod.ReturnType);

            var inputParameters = functionMethod.GetParameters().Where(c => !c.IsOut).ToArray();

            if (inputMappings == null)
            {
                inputMappings = new TableColumn[inputParameters.Length];
            }

            Inputs = new Parameter[inputMappings.Length];

            var parameterCount = 0;

            for (var i = 0; i < inputMappings.Length; i++)
            {
                if (parameterCount > inputParameters.Length)
                {
                    throw new Exception("The input parameters could not be intialized as there are " + inputMappings.Length + " input mappings, however the function only has " + inputParameters.Length + " input parameters.");
                }

                Inputs[i] = new Parameter
                {
                    Column   = inputMappings[i],
                    Name     = inputParameters[parameterCount].Name,
                    IsColumn = true
                };

                var parameterType = inputParameters[parameterCount].ParameterType;
                Inputs[i].IsArray = parameterType.IsArray;

                if (parameterType.IsArray)
                {
                    Inputs[i].DataType = GetTypeCode(parameterType.GetElementType());
                }
                else
                {
                    Inputs[i].DataType = GetTypeCode(parameterType);
                }

                //if (Inputs[i].DataType == ETypeCode.Unknown)
                //{
                //    throw new Exception("The datatype: " + inputParameters[i].GetType().ToString() + " for parameter " + inputParameters[i].Name + " is not a supported datatype.");
                //}

                //when an array is found in a method, all parameters are mapped to this.
                if (!parameterType.IsArray)
                {
                    parameterCount++;
                }
            }

            ParameterInfo[] outputParameters;

            if (ResultMethod == null)
            {
                outputParameters = functionMethod.GetParameters().Where(c => c.IsOut).ToArray();
            }
            else
            {
                outputParameters = ResultMethod.GetParameters().Where(c => c.IsOut).ToArray();
            }

            parameterCount = 0;
            if (outputParameters.Length > 0)
            {
                Outputs = new Parameter[outputParameters.Length];

                if (outputMappings == null)
                {
                    outputMappings = new TableColumn[outputParameters.Length];
                }

                for (var i = 0; i < outputMappings.Length; i++)
                {
                    if (parameterCount > inputParameters.Length)
                    {
                        throw new Exception("The output parameters could not be intialized as there are " + outputMappings.Length + " output mappings, however the function only has " + outputParameters.Length + " output parameters.");
                    }

                    Outputs[i] = new Parameter
                    {
                        Column = outputMappings[i],
                        Name   = outputParameters[parameterCount].Name
                    };

                    var parameterType = outputParameters[parameterCount].ParameterType.GetElementType();
                    Outputs[i].IsArray = parameterType.IsArray;
                    if (parameterType.IsArray)
                    {
                        Outputs[i].DataType = GetTypeCode(parameterType.GetElementType());
                    }
                    else
                    {
                        Outputs[i].DataType = GetTypeCode(parameterType);
                    }

                    //if (Outputs[i].DataType == ETypeCode.Unknown)
                    //{
                    //    throw new Exception("The datatype: " + outputParameters[i].GetType().ToString() + " for parameter " + outputParameters[i].Name + " is not a supported datatype.");
                    //}

                    //when an array is found in a method, all parameters are mapped to this.
                    if (!parameterType.IsArray)
                    {
                        parameterCount++;
                    }
                }
            }
        }