static void Set(ConcurrentDictionary<Type,ConcurrentDictionary<Type,LambdaInfo>> expressions, Type from, Type to, LambdaInfo expr) { ConcurrentDictionary<Type,LambdaInfo> dic; if (!expressions.TryGetValue(from, out dic)) expressions[from] = dic = new ConcurrentDictionary<Type, LambdaInfo>(); dic[to] = expr; }
public LambdaInfo Create(MappingSchema mappingSchema, Type from, Type to) { var ex = ConvertBuilder.GetConverter(mappingSchema, from, to); var lm = ex.Item1.Compile(); var ret = new LambdaInfo(ex.Item1, ex.Item2, lm, ex.Item3); Set(_expressions, from, to , ret); return ret; }
SqlQuery.Condition ParseAnyCondition(SetType setType, Expression expr, LambdaInfo lambda, Expression inExpr) { throw new NotImplementedException(); /* var sql = CurrentSql; var cs = _convertSource; CurrentSql = new SqlQuery(); var associationList = new Dictionary<QuerySource,QuerySource>(); _convertSource = (s,l) => { var t = s as QuerySource.Table; if (t != null && t.ParentAssociation != null) { if (ParentQueries.Count > 0) { foreach (var parentQuery in ParentQueries) { var parent = parentQuery.Parent; while (parent is QuerySource.SubQuerySourceColumn) parent = ((QuerySource.SubQuerySourceColumn)parent).SourceColumn; if (parent.Find(t.ParentAssociation)) { var orig = t; t = CreateTable(new SqlQuery(), l); associationList.Add(t, orig); var csql = CurrentSql.From.Tables.Count == 0 ? t.SqlQuery : CurrentSql; foreach (var c in orig.ParentAssociationJoin.Condition.Conditions) { var predicate = (SqlQuery.Predicate.ExprExpr)c.Predicate; csql.Where .Expr(predicate.Expr1) .Equal .Field(t.Columns[((SqlField)predicate.Expr2).Name].Field); } s = t; break; } } } } else s = cs(s, l); return s; }; var query = ParseSequence(expr)[0]; var any = CurrentSql; _convertSource = cs; if (lambda != null) { if (setType == SetType.All) { var e = Expression.Not(lambda.Body); //var pi = new NotParseInfo(e, lambda.Body); lambda = new LambdaInfo(e, lambda.Parameters); } if (inExpr == null || query.Fields.Count != 1) ParseWhere(lambda, query); } any.ParentSql = sql; CurrentSql = sql; SqlQuery.Condition cond; if (inExpr != null && query.Fields.Count == 1) { query.Select(this); var ex = ParseExpression(inExpr); cond = new SqlQuery.Condition(false, new SqlQuery.Predicate.InSubQuery(ex, false, any)); } else cond = new SqlQuery.Condition(setType == SetType.All, new SqlQuery.Predicate.FuncLike(SqlFunction.CreateExists(any))); ParsingTracer.DecIndentLevel(); return cond; */ }
/// <summary> /// Visit lambda expression for scope tracking and closure emitting purposes. /// </summary> /// <typeparam name="T">The type of the delegate represented by the lambda expression.</typeparam> /// <param name="node">The lambda expression to rewrite.</param> /// <returns>The rewritten lambda expression.</returns> protected override Expression VisitLambda <T>(Expression <T> node) { // // Allocate a slot for information about the rewritten lambda expression and thunk // type. We add a temporary empty value to the dictionary slot here in order to // boost the count of entries. This causes the index to be logically numbered in // the order the lambda expressions were visited. // var index = _lambdas.Count; _lambdas[index] = default; // // Introduce a new scope and keep track of the original scope in order to restore // it after visiting child expressions. // var currentScope = _scope; try { var scope = _analysis[node]; _scope = new CompilerScope(currentScope, scope); var body = default(Expression); if (!scope.HasHoistedLocals && !scope.NeedsClosure) { body = Visit(node.Body); } else { // // Visit the body and append it to the builder. Note that hoisted locals // (i.e. parameters) are copied into the closure. // var builder = _scope.Enter(count: 1, copyLocals: true); builder.Append(Visit(node.Body)); body = builder.Finish(declareLocals: false); } // // Use the closure parameter of the original scope (i.e. the parent to the // scope representing the lambda) to derive information about the thunk type. // var closureParam = currentScope.Closure; var thunkType = _thunkFactory.GetThunkType(typeof(T), closureParam.Type); var innerDelegateType = GetInnerDelegateType(thunkType); // // Construct a lambda that's parameterized on the closure that's passed in, // using the inner delegate type that the thunk expects. This becomes the // rewritten lambda expression, which will be passed to the constructor of // the thunk type in GetMethodTable. // var parameters = new ParameterExpression[node.Parameters.Count + 1]; parameters[0] = closureParam; node.Parameters.CopyTo(parameters, index: 1); var lambda = Expression.Lambda(innerDelegateType, body, parameters); _lambdas[index] = new LambdaInfo(lambda, thunkType); // // Inside the expression tree, replace the lambda by a call to CreateDelegate // on the thunk. The thunk is retrieved from the method table that's passed to // the top-level lambda by indexing into the Thunks array. // var createDelegate = thunkType.GetMethod(nameof(ActionThunk <object> .CreateDelegate)); var methodTable = currentScope.Bind(_methodTable); var createDelegateCall = Expression.Call( Expression.Convert( Expression.ArrayIndex( Expression.Field( methodTable, nameof(MethodTable.Thunks) ), Expression.Constant(index) ), thunkType ), createDelegate, closureParam ); return(createDelegateCall); } finally { _scope = currentScope; } }
static void Set(ConcurrentDictionary <Type, ConcurrentDictionary <Type, LambdaInfo> > expressions, Type from, Type to, LambdaInfo expr) { ConcurrentDictionary <Type, LambdaInfo> dic; if (!expressions.TryGetValue(from, out dic)) { expressions[from] = dic = new ConcurrentDictionary <Type, LambdaInfo>(); } dic[to] = expr; }
public void Set(Type from, Type to, LambdaInfo expr) { Set(_expressions, from, to, expr); }
static Expression ConverLetSubqueries(Expression expression) { var result = expression; do { expression = result; // Find let subqueries. // var dic = new Dictionary <MemberInfo, Expression>(); expression.Visit(ex => { switch (ex.NodeType) { case ExpressionType.Call: { var me = (MethodCallExpression)ex; LambdaInfo lambda = null; if (me.Method.Name == "Select" && (me.IsQueryableMethod((_, l) => { lambda = l; return(true); }) || me.IsQueryableMethod(null, 2, _ => { }, l => lambda = l))) { lambda.Body.Visit(e => { switch (e.NodeType) { case ExpressionType.New: { var ne = (NewExpression)e; if (ne.Members == null || ne.Arguments.Count != ne.Members.Count) { break; } var args = ne.Arguments.Zip(ne.Members, (a, m) => new { a, m }).ToList(); var q = from a in args where a.a.NodeType == ExpressionType.Call && a.a.Type != typeof(string) && !a.a.Type.IsArray && TypeHelper.GetGenericType(typeof(IEnumerable <>), a.a.Type) != null select a; foreach (var item in q) { dic.Add(item.m, item.a); } } break; } }); } } break; } }); if (dic.Count == 0) { return(expression); } result = expression.Convert(ex => { switch (ex.NodeType) { case ExpressionType.MemberAccess: { var me = (MemberExpression)ex; var member = me.Member; if (member is PropertyInfo) { member = ((PropertyInfo)member).GetGetMethod(); } Expression arg; if (dic.TryGetValue(member, out arg)) { return(arg); } } break; } return(ex); }); } while (result != expression); return(expression); }