Inheritance: System.Linq.Expressions.Expression
        //internal static Expression JustVisit(LambdaExpression expression, PropertyRoute route)
        //{
        //    if (route.Type.IsLite())
        //        route = route.Add("Entity");

        //    return JustVisit(expression, ));
        //}

        internal static Expression JustVisit(LambdaExpression expression, MetaExpression metaExpression)
        {
            var cleaned = MetaEvaluator.Clean(expression);

            var replaced = ExpressionReplacer.Replace(Expression.Invoke(cleaned, metaExpression));

            return(new MetadataVisitor().Visit(replaced));
        }
Beispiel #2
0
        //internal static Expression JustVisit(LambdaExpression expression, PropertyRoute route)
        //{
        //    if (route.Type.IsLite())
        //        route = route.Add("Entity");

        //    return JustVisit(expression, ));
        //}

        internal static Expression JustVisit(LambdaExpression expression, MetaExpression metaExpression)
        {
            var cleaned = MetaEvaluator.Clean(expression);

            var replaced = ExpressionReplacer.Replace(Expression.Invoke(cleaned, metaExpression));

            return new MetadataVisitor().Visit(replaced);
        }
Beispiel #3
0
        public static MetaProjectorExpression AsProjection(Expression expression)
        {
            MetaProjectorExpression mpe = expression as MetaProjectorExpression;

            if (mpe != null)
            {
                return((MetaProjectorExpression)mpe);
            }

            if (expression.NodeType == ExpressionType.New)
            {
                NewExpression nex = (NewExpression)expression;
                if (nex.Type.IsInstantiationOf(typeof(Grouping <,>)))
                {
                    return((MetaProjectorExpression)nex.Arguments[1]);
                }
            }

            Type elementType = expression.Type.ElementType();

            if (elementType != null)
            {
                MetaExpression meta = expression as MetaExpression;
                if (meta != null && meta.Meta is CleanMeta)
                {
                    PropertyRoute route = ((CleanMeta)meta.Meta).PropertyRoutes.SingleEx(() => "PropertyRoutes for {0}. Metas don't work over polymorphic MLists".FormatWith(meta.Meta)).Add("Item");

                    return(new MetaProjectorExpression(expression.Type,
                                                       new MetaExpression(elementType,
                                                                          new CleanMeta(route.TryGetImplementations(), route))));
                }

                return(new MetaProjectorExpression(expression.Type,
                                                   MakeVoidMeta(elementType)));
            }

            throw new InvalidOperationException();
        }
        static MetaExpression MakeCleanMeta(Type type, Expression expression)
        {
            MetaExpression meta = (MetaExpression)expression;

            return(new MetaExpression(type, meta.Meta));
        }
        static Expression BindMember(Expression source, MemberInfo member, Type memberType)
        {
            switch (source.NodeType)
            {
            case ExpressionType.MemberInit:
                return(((MemberInitExpression)source).Bindings
                       .OfType <MemberAssignment>()
                       .SingleEx(a => ReflectionTools.MemeberEquals(a.Member, member)).Expression);

            case ExpressionType.New:
                NewExpression nex = (NewExpression)source;
                if (nex.Type.IsInstantiationOf(typeof(Grouping <,>)) && member.Name == "Key")
                {
                    return(nex.Arguments[0]);
                }

                if (nex.Members != null)
                {
                    PropertyInfo pi = (PropertyInfo)member;
                    return(nex.Members.Zip(nex.Arguments).SingleEx(p => ReflectionTools.PropertyEquals((PropertyInfo)p.first, pi)).second);
                }
                break;
            }

            if (source is MetaMListExpression mme)
            {
                var ga = mme.Type.GetGenericArguments();
                if (member.Name == "Parent")
                {
                    return(new MetaExpression(ga[0], mme.Parent));
                }

                if (member.Name == "Element")
                {
                    return(new MetaExpression(ga[1], mme.Element));
                }

                throw new InvalidOperationException("Property {0} not found on {1}".FormatWith(member.Name, mme.Type.TypeName()));
            }

            if (typeof(ModifiableEntity).IsAssignableFrom(source.Type) || typeof(IEntity).IsAssignableFrom(source.Type))
            {
                var pi = member as PropertyInfo ?? Reflector.TryFindPropertyInfo((FieldInfo)member);

                if (pi == null)
                {
                    return(new MetaExpression(memberType, null));
                }

                MetaExpression meta = (MetaExpression)source;

                if (meta.Meta.Implementations != null)
                {
                    var routes = meta.Meta.Implementations.Value.Types.Select(t => PropertyRoute.Root(t).Add(pi)).ToArray();

                    return(new MetaExpression(memberType, new CleanMeta(GetImplementations(routes, memberType), routes)));
                }

                if (meta.Meta is CleanMeta)
                {
                    PropertyRoute[] routes = ((CleanMeta)meta.Meta).PropertyRoutes.Select(r => r.Add(pi.Name)).ToArray();

                    return(new MetaExpression(memberType, new CleanMeta(GetImplementations(routes, memberType), routes)));
                }

                if (typeof(Entity).IsAssignableFrom(source.Type) && !source.Type.IsAbstract) //Works for simple entities and also for interface casting
                {
                    var pr = PropertyRoute.Root(source.Type).Add(pi);

                    return(new MetaExpression(memberType, new CleanMeta(pr.TryGetImplementations(), pr)));
                }
            }

            if (source.Type.IsLite() && member.Name == "Entity")
            {
                MetaExpression meta = (MetaExpression)source;

                if (meta.Meta is CleanMeta)
                {
                    PropertyRoute[] routes = ((CleanMeta)meta.Meta).PropertyRoutes.Select(pr => pr.Add("Entity")).ToArray();

                    return(new MetaExpression(memberType, new CleanMeta(meta.Meta.Implementations, routes)));
                }
            }

            return(MakeDirtyMeta(memberType, null, source));
        }