public static MetaProjectorExpression AsProjection(Expression expression) { if (expression is MetaProjectorExpression mpe) { return(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) { if (expression is MetaExpression meta && 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(); }
protected override Expression VisitConstant(ConstantExpression c) { Type type = TableType(c.Value); if (type != null) { if (typeof(Entity).IsAssignableFrom(type)) { return(new MetaProjectorExpression(c.Type, new MetaExpression(type, new CleanMeta(Implementations.By(type), PropertyRoute.Root(type))))); } if (type.IsInstantiationOf(typeof(MListElement <,>))) { var parentType = type.GetGenericArguments()[0]; ISignumTable st = (ISignumTable)c.Value; TableMList rt = (TableMList)st.Table; PropertyRoute element = rt.PropertyRoute.Add("Item"); return(new MetaProjectorExpression(c.Type, new MetaMListExpression(type, new CleanMeta(Implementations.By(parentType), PropertyRoute.Root(rt.PropertyRoute.RootType)), new CleanMeta(element.TryGetImplementations(), element)))); } } return(MakeVoidMeta(c.Type)); }