protected internal virtual ExtensionToken CreateToken(QueryToken parent) { var info = metas.GetOrAdd(parent, qt => { Expression e = MetadataVisitor.JustVisit(Lambda, MetaExpression.FromToken(qt, SourceType)); MetaExpression me; if (this.IsProjection) { var mpe = e as MetaProjectorExpression; if (mpe == null) { mpe = MetadataVisitor.AsProjection(e); } me = mpe == null ? null : mpe.Projector as MetaExpression; } else { me = e as MetaExpression; } CleanMeta cm = me == null ? null : me.Meta as CleanMeta; var result = new ExtensionRouteInfo(); if (cm != null && cm.PropertyRoutes.Any()) { var cleanType = me.Type.CleanType(); result.PropertyRoute = cm.PropertyRoutes.Only(); result.Implementations = me.Meta.Implementations; result.Format = ColumnDescriptionFactory.GetFormat(cm.PropertyRoutes); result.Unit = ColumnDescriptionFactory.GetUnit(cm.PropertyRoutes); } result.IsAllowed = () => (me == null || me.Meta == null) ? null : me.Meta.IsAllowed(); if (ForcePropertyRoute != null) { result.PropertyRoute = ForcePropertyRoute; } if (ForceImplementations != null) { result.Implementations = ForceImplementations; } if (ForceFormat != null) { result.Format = ForceFormat; } if (ForceUnit != null) { result.Unit = ForceUnit; } if (ForceIsAllowed != null) { result.IsAllowed = ForceIsAllowed; } return(result); }); return(new ExtensionToken(parent, Key, Type, IsProjection, info.Unit, info.Format, info.Implementations, info.IsAllowed(), info.PropertyRoute) { DisplayName = NiceName() }); }
protected override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Queryable) || m.Method.DeclaringType == typeof(Enumerable) || m.Method.DeclaringType == typeof(EnumerableUniqueExtensions)) { switch (m.Method.Name) { case "Where": return(this.BindWhere(m.Type, m.GetArgument("source"), m.GetArgument("predicate").StripQuotes())); case "Select": return(this.BindSelect(m.Type, m.GetArgument("source"), m.GetArgument("selector").StripQuotes())); case "SelectMany": if (m.Arguments.Count == 2) { return(this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("selector").StripQuotes(), null)); } else { return(this.BindSelectMany(m.Type, m.GetArgument("source"), m.GetArgument("collectionSelector").StripQuotes(), m.TryGetArgument("resultSelector").StripQuotes())); } case "Join": return(this.BindJoin( m.Type, m.GetArgument("outer"), m.GetArgument("inner"), m.GetArgument("outerKeySelector").StripQuotes(), m.GetArgument("innerKeySelector").StripQuotes(), m.GetArgument("resultSelector").StripQuotes())); case "OrderBy": return(this.BindOrderBy(m.Type, m.GetArgument("source"), m.GetArgument("keySelector").StripQuotes(), OrderType.Ascending)); case "OrderByDescending": return(this.BindOrderBy(m.Type, m.GetArgument("source"), m.GetArgument("keySelector").StripQuotes(), OrderType.Descending)); case "ThenBy": return(this.BindThenBy(m.GetArgument("source"), m.GetArgument("keySelector").StripQuotes(), OrderType.Ascending)); case "ThenByDescending": return(this.BindThenBy(m.GetArgument("source"), m.GetArgument("keySelector").StripQuotes(), OrderType.Descending)); case "GroupBy": return(this.BindGroupBy(m.Type, m.GetArgument("source"), m.GetArgument("keySelector").StripQuotes(), m.GetArgument("elementSelector").StripQuotes())); case "Count": return(this.BindCount(m.Type, m.GetArgument("source"))); case "DefaultIfEmpty": return(Visit(m.GetArgument("source"))); case "Any": return(this.BindAny(m.Type, m.GetArgument("source"))); case "All": return(this.BindAll(m.Type, m.GetArgument("source"), m.GetArgument("predicate").StripQuotes())); case "Contains": return(this.BindContains(m.Type, m.GetArgument("source"), m.TryGetArgument("item") ?? m.GetArgument("value"))); case "Sum": case "Min": case "Max": case "Average": return(this.BindAggregate(m.Type, m.Method.Name.ToEnum <AggregateSqlFunction>(), m.GetArgument("source"), m.TryGetArgument("selector").StripQuotes())); case "First": case "FirstOrDefault": case "Single": case "SingleOrDefault": return(BindUniqueRow(m.Type, m.Method.Name.ToEnum <UniqueFunction>(), m.GetArgument("source"), m.TryGetArgument("predicate").StripQuotes())); case "FirstEx": case "SingleEx": case "SingleOrDefaultEx": return(BindUniqueRow(m.Type, m.Method.Name.RemoveEnd(2).ToEnum <UniqueFunction>(), m.GetArgument("collection"), m.TryGetArgument("predicate").StripQuotes())); case "Distinct": return(BindDistinct(m.Type, m.GetArgument("source"))); case "Take": return(BindTake(m.Type, m.GetArgument("source"), m.GetArgument("count"))); case "Skip": return(BindSkip(m.Type, m.GetArgument("source"), m.GetArgument("count"))); } } if (m.Method.Name == "Mixin" && m.Method.GetParameters().Length == 0) { var obj = Visit(m.Object); if (obj is MetaExpression me && me.Meta is CleanMeta) { CleanMeta cm = (CleanMeta)me.Meta; var mixinType = m.Method.GetGenericArguments().Single(); return(new MetaExpression(mixinType, new CleanMeta(null, cm.PropertyRoutes.Select(a => a.Add(mixinType)).ToArray()))); } } if (m.Method.DeclaringType == typeof(LinqHints) || m.Method.DeclaringType == typeof(LinqHintEntities)) { return(Visit(m.Arguments[0])); } if (m.Method.DeclaringType == typeof(StringExtensions) && m.Method.Name == nameof(StringExtensions.Etc)) { return(Visit(m.Arguments[0])); } if (m.Method.DeclaringType == typeof(Lite) && m.Method.Name == "ToLite") { return(MakeCleanMeta(m.Type, Visit(m.Arguments[0]))); } if (m.Method.DeclaringType == typeof(Math) && (m.Method.Name == "Abs" || m.Method.Name == "Ceiling" || m.Method.Name == "Floor" || m.Method.Name == "Round" || m.Method.Name == "Truncate")) { return(MakeCleanMeta(m.Type, Visit(m.Arguments[0]))); } if (m.Method.Name == "ToString" && m.Object != null && typeof(IEntity).IsAssignableFrom(m.Object.Type)) { return(Visit(Expression.Property(m.Object, piToStringProperty))); } if (m.Object != null) { var a = this.Visit(m.Object); var list = this.Visit(m.Arguments); return(MakeDirtyMeta(m.Type, null, list.PreAnd(a).ToArray())); } else { var list = this.Visit(m.Arguments); return(MakeDirtyMeta(m.Type, null, list.ToArray())); } }
public MetaMListExpression(Type type, CleanMeta parent, CleanMeta element) : base(MetaExpressionType.MetaMListExpression, type) { this.Parent = parent; this.Element = element; }