//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)); }
//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); }
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)); }