Exemple #1
0
        public override Expression BuildExpression(ParameterExpression paramExpression)
        {
            // Get underlying type of IEnumerable
            if (!paramExpression.Type.GetInterfaces().Contains(typeof(IEnumerable)))
            {
                throw new Exception($"DataContext (paramExpression: {paramExpression.Type.ToString()}) must implement IEnumerable. Where apply over IEnumerable<T>");
            }

            if (paramExpression.Type.GenericTypeArguments.Length == 0)
            {
                throw new Exception($"DataContext (paramExpression: {paramExpression.Type.ToString()}) must have one generic parameter: IEnumerable<T>");
            }

            Type underlyingTypeList = paramExpression.Type.GenericTypeArguments.First();
            Type ienumerableType    = typeof(IEnumerable <>).MakeGenericType(underlyingTypeList);

            MethodInfo firstMethod     = (MethodInfo)ClassMetadataLocator.GetGenericMethod(typeof(Enumerable), nameof(Enumerable.FirstOrDefault), new[] { underlyingTypeList }, new[] { ienumerableType }, BindingFlags.Static);;
            Expression firstExpression = Expression.Call(firstMethod, paramExpression);

            Expression propertyExpression = Expression.Property(firstExpression, SelectedProperty);

            // Check types
            Type internalType = new TPrimitiveType().InternalType;

            if (propertyExpression.Type != internalType)
            {
                return(Expression.Convert(propertyExpression, internalType));
            }
            else
            {
                return(propertyExpression);
            }
        }
Exemple #2
0
        public override Expression BuildExpression(ParameterExpression paramExpression)
        {
            // Extract underlying type of List
            Type underlyingTypeList = paramExpression.Type.GenericTypeArguments.First();
            // Create a new parameter
            ParameterExpression newParameter = Expression.Parameter(underlyingTypeList, "newParameter");
            // Create generic IEnumerable<>
            Type ienumerableType = typeof(IEnumerable <>).MakeGenericType(underlyingTypeList);

            // Count()
            MethodInfo countMethod = (MethodInfo)ClassMetadataLocator.GetGenericMethod(typeof(Enumerable), nameof(Enumerable.Count), new[] { underlyingTypeList }, new[] { ienumerableType }, BindingFlags.Static);

            return(Expression.Convert(Expression.Call(countMethod, paramExpression), typeof(double))); // Auto conversion to double
        }
        public override Expression BuildExpression(ParameterExpression paramExpression)
        {
            // Extract underlying type of List
            Type underlyingTypeList = paramExpression.Type.GenericTypeArguments.First();
            // Create a new parameter
            ParameterExpression newParameter = Expression.Parameter(underlyingTypeList, "p");
            // Create generic IEnumerable<>
            Type ienumerableType = typeof(IEnumerable <>).MakeGenericType(underlyingTypeList);

            MethodInfo geoMethod = GetType().GetMethod(nameof(GetGeometricMean), BindingFlags.NonPublic | BindingFlags.Static);

            Expression geoExpression = null;

            if (!string.IsNullOrEmpty(SelectedProperty))
            {
                // Geo(p => p.selectedProperty)
                Type propertyType = ClassMetadataLocator.GetPropertyType(underlyingTypeList, SelectedProperty);

                Type funcType = typeof(Func <,>).MakeGenericType(underlyingTypeList, propertyType);

                // Proyección Select
                Expression selectExpression = Expression.Lambda(Expression.Property(newParameter, SelectedProperty), newParameter);
                MethodInfo selectMethod     = (MethodInfo)ClassMetadataLocator.GetGenericMethod(typeof(Enumerable), nameof(Enumerable.Select), new[] { underlyingTypeList, propertyType }, new[] { ienumerableType, funcType }, BindingFlags.Static);

                Expression projectionExpression = Expression.Call(selectMethod,
                                                                  paramExpression,
                                                                  selectExpression);

                geoExpression = Expression.Call(geoMethod, projectionExpression);
            }
            else
            {
                // Geo(IEnumerable<PrimitiveType>)
                geoExpression = Expression.Call(geoMethod, paramExpression);
            }

            Type internalType = new TArithmeticType().InternalType;

            if (geoExpression.Type != internalType)
            {
                return(Expression.Convert(geoExpression, internalType));
            }

            return(geoExpression);
        }
Exemple #4
0
        public override Expression BuildExpression(ParameterExpression paramExpression)
        {
            // Extract underlying type of List
            Type underlyingTypeList = paramExpression.Type.GenericTypeArguments.First();
            // Create a new parameter
            ParameterExpression newParameter = Expression.Parameter(underlyingTypeList, "newParameter");
            // Create generic IEnumerable<>
            Type iEnumerableType = typeof(IEnumerable <>).MakeGenericType(underlyingTypeList);

            Expression avgExpression = null;

            if (!string.IsNullOrEmpty(SelectedProperty))
            {
                // Avg(p => p.NombrePropiedad)
                Type propertyType = ClassMetadataLocator.GetPropertyType(underlyingTypeList, SelectedProperty);

                Type funcType = typeof(Func <,>).MakeGenericType(underlyingTypeList, propertyType);

                MethodInfo averageMethod = (MethodInfo)ClassMetadataLocator.GetGenericMethod(typeof(Enumerable), nameof(Enumerable.Average), new[] { underlyingTypeList }, new[] { iEnumerableType, funcType }, BindingFlags.Static);

                Expression propertyProjection = Expression.Lambda(Expression.Property(newParameter, SelectedProperty),
                                                                  newParameter);

                avgExpression = Expression.Call(averageMethod, paramExpression, propertyProjection);
            }
            else
            {
                // Avg(IEnumerable<PrimitiveType>)
                MethodInfo avgMethod = typeof(Enumerable).GetMethods().Single(m => m.Name == nameof(Enumerable.Average) &&
                                                                              m.GetParameters().Length == 1 &&
                                                                              m.GetParameters()[0].ParameterType == iEnumerableType);
                avgExpression = Expression.Call(avgMethod, paramExpression);
            }

            Type internalType = new TArithmeticType().InternalType;

            if (avgExpression.Type != internalType)
            {
                return(Expression.Convert(avgExpression, internalType));
            }

            return(avgExpression);
        }
Exemple #5
0
        public override Expression BuildExpression(ParameterExpression paramExpression)
        {
            ParameterExpression paramExpressionI = Expression.Parameter(typeof(string), "i");
            ParameterExpression paramExpressionJ = Expression.Parameter(typeof(string), "j");

            MethodInfo stringConcat = typeof(string).GetMethod(nameof(string.Concat), new Type[] { typeof(string), typeof(string), typeof(string) });

            // Concatenación
            Expression concatExpression = Expression.Call(stringConcat,
                                                          paramExpressionI, Expression.Constant(Delimiter), paramExpressionJ);

            Type ienumerableType = typeof(IEnumerable <>).MakeGenericType(typeof(string));
            Type funcType        = typeof(Func <, ,>).MakeGenericType(typeof(string), typeof(string), typeof(string));

            // public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
            MethodInfo aggregateMethod = (MethodInfo)ClassMetadataLocator.GetGenericMethod(typeof(Enumerable), nameof(Enumerable.Aggregate), new[] { typeof(string) }, new[] { ienumerableType, funcType }, BindingFlags.Static);

            // Select
            // public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
            Type underlyingTypeList          = paramExpression.Type.GenericTypeArguments.First();
            ParameterExpression newParameter = Expression.Parameter(underlyingTypeList, "newParameter");

            Expression selectExpression = Expression.Lambda(Expression.Property(newParameter, SelectedProperty), newParameter);
            MethodInfo selectMethod     = (MethodInfo)ClassMetadataLocator.GetGenericMethod(typeof(Enumerable),
                                                                                            nameof(Enumerable.Select),
                                                                                            new[] { underlyingTypeList, typeof(string) },
                                                                                            new[] { paramExpression.Type, typeof(Func <,>).MakeGenericType(underlyingTypeList, typeof(string)) },
                                                                                            BindingFlags.Static);

            Expression projection = Expression.Call(selectMethod,
                                                    paramExpression,
                                                    selectExpression);

            return(Expression.Call(aggregateMethod,
                                   projection,
                                   Expression.Lambda(concatExpression, paramExpressionI, paramExpressionJ)));
        }