public static void EvaluateLocals(DynamicLinqCommand command) { var locals = command.Locals; if (locals.Count == 0) { command.ParamValues = _emptyArray; return; } // evaluate external parameters - they come from OperationContext var extValues = _emptyArray; if (command.ExternalParameters != null && command.ExternalParameters.Length > 0) { var ctx = command.Session.Context; extValues = new object[command.ExternalParameters.Length]; for (int i = 0; i < extValues.Length; i++) { extValues[i] = LinqExpressionHelper.EvaluateContextParameterExpression(command.Session, command.ExternalParameters[i]); } //for i } //if // evaluate locals command.ParamValues = new object[locals.Count]; for (int i = 0; i < locals.Count; i++) { var local = locals[i]; command.ParamValues[i] = ExpressionHelper.Evaluate(locals[i], command.ExternalParameters, extValues); } } //method
private void RewriteCommand(DynamicLinqCommand command) { _model = command.Session.Context.App.Model; _command = command; _locals = command.Locals; //create parameters _parameters = new List <ParameterExpression>(); for (int i = 0; i < _locals.Count; i++) { var local = _locals[i]; var prm = local.NodeType == ExpressionType.Parameter ? (ParameterExpression)local : Expression.Parameter(local.Type, "@P" + i); _parameters.Add(prm); } var body = this.Visit(_command.QueryExpression); _command.Lambda = Expression.Lambda(body, _parameters); }
private void AnalyzeCommand(DynamicLinqCommand command) { _command = command; _model = command.Session.Context.App.Model; _cacheKeyBuilder = new SqlCacheKeyBuilder("Linq", command.Kind.ToString(), command.Operation.ToString()); try { AnalyzeNode(_command.QueryExpression); //copy some values to command command.SqlCacheKey = _cacheKeyBuilder.Key; command.EntityTypes = _entityTypes; command.LockType = _lockType; command.Includes = _includes; command.Options |= _options; command.Locals.AddRange(_locals); command.ExternalParameters = _externalParams?.ToArray(); if (command.Locals.Count > 0) { LinqExpressionHelper.EvaluateLocals(command); } } catch (Exception ex) { ex.Data["LinqExperssion"] = _command.QueryExpression + string.Empty; throw; } }
public SqlStatement TranslateNonQuery(DynamicLinqCommand command) { var translCtx = new TranslationContext(_dbModel, command); // convert lambda params into an initial set of ExternalValueExpression objects; foreach (var prm in command.Lambda.Parameters) { var inpParam = new ExternalValueExpression(prm); translCtx.ExternalValues.Add(inpParam); } //Analyze/transform base select query var selectExpr = TranslateSelectExpression(command, translCtx); var targetEnt = command.UpdateEntity; var targetTable = _dbModel.GetTable(targetEnt.EntityType); var nonQueryCmd = new NonQueryLinqCommand(command, targetTable, selectExpr); // Analyze base query output expression var targetTableExpr = new TableExpression(targetTable); var readerBody = selectExpr.RowReaderLambda.Body; switch (nonQueryCmd.Operation) { case LinqOperation.Update: case LinqOperation.Insert: Util.Check(readerBody.NodeType == ExpressionType.New, "Query for LINQ {0} command must return New object", nonQueryCmd.Operation); var newExpr = readerBody as NewExpression; var outValues = selectExpr.Operands.ToList(); for (int i = 0; i < newExpr.Members.Count; i++) { var memberName = newExpr.Members[i].Name; var memberInfo = targetEnt.GetMember(memberName); Util.Check(memberInfo != null, "Member {0} not found in entity {1}.", memberName, targetEnt, targetEnt.EntityType); switch (memberInfo.Kind) { case EntityMemberKind.Column: var col = _translator.CreateColumnForMember(targetTableExpr, memberInfo, translCtx); nonQueryCmd.TargetColumns.Add(col.ColumnInfo); nonQueryCmd.SelectOutputValues.Add(outValues[i]); break; case EntityMemberKind.EntityRef: var fromKey = memberInfo.ReferenceInfo.FromKey; Util.Check(fromKey.ExpandedKeyMembers.Count == 1, "References with composite keys are not supported in LINQ non-query operations. Reference: ", memberName); var pkMember = fromKey.ExpandedKeyMembers[0].Member; var col2 = _translator.CreateColumnForMember(targetTableExpr, pkMember, translCtx); nonQueryCmd.TargetColumns.Add(col2.ColumnInfo); nonQueryCmd.SelectOutputValues.Add(outValues[i]); break; default: Util.Throw("Property cannot be used in the context: {0}.", memberName); break; } } break; case LinqOperation.Delete: nonQueryCmd.SelectOutputValues.Add(readerBody); //should return single value - primary key break; } // Build SQL var sqlBuilder = _dbModel.Driver.CreateLinqNonQuerySqlBuilder(_dbModel, nonQueryCmd); var stmt = sqlBuilder.BuildLinqNonQuerySql(); return(stmt); } //method
public static void Analyze(DynamicLinqCommand command) { var scanner = new LinqCommandAnalyzer(); scanner.AnalyzeCommand(command); }
public static void RewriteToLambda(DynamicLinqCommand command) { var rewriter = new LinqCommandRewriter(); rewriter.RewriteCommand(command); }