예제 #1
0
 protected override Expression VisitLambda <T>(Expression <T> node)
 {
     if (node.Body is NewExpression && ((NewExpression)node.Body).Type == typeof(DynamicObjectClass))
     {
         var e           = node.Body as NewExpression;
         var properties  = new List <DynamicProperty>(e.Arguments.Count);
         var expressions = new List <Expression>(e.Arguments.Count);
         foreach (NewExpression newEx in e.Arguments)
         {
             var name      = ((ConstantExpression)newEx.Arguments.First()).Value as string;
             var parameter = ((UnaryExpression)newEx.Arguments.Skip(1).First()).Operand;
             properties.Add(new DynamicProperty(name, parameter.Type));
             expressions.Add(parameter);
         }
         Type            type     = DynamicExpression.CreateClass(properties);
         MemberBinding[] bindings = new MemberBinding[properties.Count];
         for (int i = 0; i < bindings.Length; i++)
         {
             bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);
         }
         var        membInit      = Expression.MemberInit(Expression.New(type), bindings);
         var        typeOfTArgs   = typeof(T).GetGenericArguments();
         var        funcTType     = typeof(Func <,>).MakeGenericType(new[] { typeOfTArgs.First(), type });
         var        mi            = typeof(Expression).GetMethods().FirstOrDefault(x => x.Name == "Lambda" && x.ContainsGenericParameters);
         MethodInfo genericMethod = mi.MakeGenericMethod(new[] { funcTType });
         var        lambda        = genericMethod.Invoke(null, new object[] { membInit, node.Parameters.ToArray() }) as Expression;
         return(lambda);
     }
     return(base.VisitLambda <T>(node));
 }
예제 #2
0
        private static object PrepareAggregate <T>(IQueryable <T> queryable, Query q)
        {
            var aggregates = q.Aggregates;

            if (aggregates != null && aggregates.Any())
            {
                var  objProps = new Dictionary <DynamicProperty, object>();
                var  groups   = aggregates.GroupBy(g => g.ColumnName);
                Type type     = null;
                foreach (var group in groups)
                {
                    var fieldProps = new Dictionary <DynamicProperty, object>();
                    foreach (var aggregate in group)
                    {
                        var prop     = typeof(T).GetProperty(aggregate.ColumnName);
                        var param    = Expression.Parameter(typeof(T), "s");
                        var selector = aggregate.Aggregate == "count" && (Nullable.GetUnderlyingType(prop.PropertyType) != null)
                            ? Expression.Lambda(Expression.NotEqual(Expression.MakeMemberAccess(param, prop), Expression.Constant(null, prop.PropertyType)), param)
                            : Expression.Lambda(Expression.MakeMemberAccess(param, prop), param);
                        var mi = aggregate.MethodInfo(typeof(T));
                        if (mi == null)
                        {
                            continue;
                        }

                        var val = queryable.Provider.Execute(Expression.Call(null, mi,
                                                                             aggregate.Aggregate == "count" && (Nullable.GetUnderlyingType(prop.PropertyType) == null)
                                ? new[] { queryable.Expression }
                                : new[] { queryable.Expression, Expression.Quote(selector) }));

                        fieldProps.Add(new DynamicProperty(aggregate.Aggregate, typeof(object)), val);
                    }
                    type = DynamicExpression.CreateClass(fieldProps.Keys);
                    var fieldObj = Activator.CreateInstance(type);
                    foreach (var p in fieldProps.Keys)
                    {
                        type.GetProperty(p.Name).SetValue(fieldObj, fieldProps[p], null);
                    }
                    objProps.Add(new DynamicProperty(group.Key, fieldObj.GetType()), fieldObj);
                }

                type = DynamicExpression.CreateClass(objProps.Keys);

                var obj = Activator.CreateInstance(type);

                foreach (var p in objProps.Keys)
                {
                    type.GetProperty(p.Name).SetValue(obj, objProps[p], null);
                }

                return(obj);
            }
            else
            {
                return(null);
            }
        }
예제 #3
0
        public static object Aggregate <T>(this IQueryable <T> queryable, IEnumerable <Aggregator> aggregates)
        {
            if (aggregates == null)
            {
                return(null);
            }

            var aggregators = aggregates as Aggregator[] ?? aggregates.ToArray();

            if (!aggregators.Any())
            {
                return(null);
            }

            var  objProps = new Dictionary <DynamicProperty, object>();
            var  groups   = aggregators.GroupBy(g => g.Field);
            Type type;

            foreach (var group in groups)
            {
                var fieldProps = new Dictionary <DynamicProperty, object>();
                foreach (var aggregate in group)
                {
                    var prop = typeof(T).GetProperty(aggregate.Field);
                    if (prop == null)
                    {
                        throw new InvalidOperationException($"{aggregate.Field} Property does not exists!");
                    }

                    var param    = Expression.Parameter(typeof(T), "s");
                    var selector = aggregate.Aggregate == "count" &&
                                   Nullable.GetUnderlyingType(prop.PropertyType) != null
                        ? Expression.Lambda(
                        Expression.NotEqual(Expression.MakeMemberAccess(param, prop),
                                            Expression.Constant(null, prop.PropertyType)), param)
                        : Expression.Lambda(Expression.MakeMemberAccess(param, prop), param);

                    var mi = aggregate.MethodInfo(typeof(T));
                    if (mi == null)
                    {
                        continue;
                    }

                    var val = queryable.Provider.Execute(Expression.Call(null, mi,
                                                                         aggregate.Aggregate == "count" && Nullable.GetUnderlyingType(prop.PropertyType) == null
                            ? new[] { queryable.Expression }
                            : new[] { queryable.Expression, Expression.Quote(selector) }));

                    fieldProps.Add(new DynamicProperty(aggregate.Aggregate, typeof(object)), val);
                }
                type = DynamicExpression.CreateClass(fieldProps.Keys);
                var fieldObj = Activator.CreateInstance(type);
                foreach (var p in fieldProps.Keys)
                {
                    type.GetProperty(p.Name).SetValue(fieldObj, fieldProps[p], null);
                }
                objProps.Add(new DynamicProperty(group.Key, fieldObj.GetType()), fieldObj);
            }

            type = DynamicExpression.CreateClass(objProps.Keys);

            var obj = Activator.CreateInstance(type);

            foreach (var p in objProps.Keys)
            {
                type.GetProperty(p.Name).SetValue(obj, objProps[p], null);
            }

            return(obj);
        }