public static void PreprocessCommand(EntityModel model, LinqCommand command)
 {
     if (command.Info.Lambda != null)
     return;
       var preProc = new LinqCommandPreprocessor();
       preProc.Preprocess(model, command);
 }
 public LinqTranslationException(string message, LinqCommand command, Exception inner = null)
     : base(message, inner)
 {
     Command = command;
       if (Command != null)
     this.Data["LinqCommand"] = Command.ToString();
 }
 public NonQueryLinqCommandData(LinqCommand baseLinqCommand, SelectExpression baseSelect, TableExpression targetTable, bool isSingleTable)
 {
     BaseLinqCommand = baseLinqCommand;
       BaseSelect = baseSelect;
       TargetTable = targetTable;
       IsSingleTableCommand = isSingleTable;
 }
Example #4
0
 public static void RunIncludeQueries(IEntitySession session, LinqCommand command, object mainQueryResult)
 {
     // initial checks if there's anything to run
       var resultShape = command.Info.ResultShape;
       if (mainQueryResult == null || resultShape == QueryResultShape.Object)
     return;
       var allIncludes = session.Context.GetMergedIncludes(command.Info.Includes);
       if (allIncludes.Count == 0)
     return;
       // Get records from query result
       var records = new List<EntityRecord>();
       switch (resultShape) {
     case QueryResultShape.Entity:
       records.Add(EntityHelper.GetRecord(mainQueryResult));
       break;
     case QueryResultShape.EntityList:
       var list = mainQueryResult as IList;
       if (list.Count == 0)
     return;
       foreach (var ent in list)
     records.Add(EntityHelper.GetRecord(ent));
       break;
       }//switch;
       // actually run the includes
       var entityType = records[0].EntityInfo.EntityType;
       var helper = new IncludeQueryHelper(session, allIncludes);
       helper.RunIncludeQueries(entityType, records);
 }
Example #5
0
        public TranslatedLinqCommand Translate(LinqCommand command)
        {
            if (command.Info == null)
            LinqCommandAnalyzer.Analyze(_dbModel.EntityApp.Model, command);
              try {
            switch(command.CommandType) {
              case LinqCommandType.Select:
                return TranslateSelect(command);
              case LinqCommandType.Update:
              case LinqCommandType.Delete:
              case LinqCommandType.Insert:
                return TranslateNonQuery(command);
              default:
                ThrowTranslationFailed(command, "Unsupported LINQ command type.");
                return null;

            }
              } catch(LinqTranslationException) {
            throw; // if it is alread Linq translation exception, pass it up.
              } catch (Exception ex) {
            var message = "Linq to SQL translation failed: " + ex.Message +
                       "\r\nPossibly facilities you are trying to use are not supported. " +
                       "\r\nTry to reformulate/simplify the query. Hint: do not use c# functions/methods inside query directly. ";
            throw new LinqTranslationException(message, command, ex);
              }
        }
Example #6
0
 private object ExecuteLinqNonQuery(LinqCommand linqCommand, EntitySession session, DataConnection connection)
 {
     var translCmd = GetTranslateLinqCommand(linqCommand);
       var dbCommand = CreateLinqDbCommand(connection, linqCommand, translCmd);
       var result = ExecuteDbCommand(dbCommand, connection, DbExecutionType.NonQuery);
       return result;
 }
Example #7
0
        public static void PreprocessCommand(EntityModel model, LinqCommand command)
        {
            if (command.Info.Lambda != null)
            {
                return;
            }
            var preProc = new LinqCommandPreprocessor();

            preProc.Preprocess(model, command);
        }
Example #8
0
 public TranslationContext(TranslationContext source)
 {
     this.DbModel = source.DbModel;
       this.Command = source.Command;
       this.CallStack = source.CallStack;
       this.ExternalValues = source.ExternalValues;
       this.MetaTables = source.MetaTables;
       this.SelectExpressions = source.SelectExpressions;
       this.LambdaParameters = source.LambdaParameters;
       this._currentScopeIndex = source._currentScopeIndex;
 }
Example #9
0
 public TranslationContext(DbModel dbModel, LinqCommand command)
 {
     DbModel = dbModel;
       Command = command;
       CallStack = new Stack<MethodInfo>();
       SelectExpressions = new List<SelectExpression>();
       _currentScopeIndex = SelectExpressions.Count;
       SelectExpressions.Add(new SelectExpression());
       ExternalValues = new List<ExternalValueExpression>();
       MetaTables = new List<MetaTableExpression>();
       LambdaParameters = new Dictionary<string, Expression>();
 }
Example #10
0
        public static LinqCommandInfo Analyze(EntityModel model, LinqCommand command)
        {
            // if the query was already analyzed, return the old object; otherwise analyze and save in query's field
            if (command.Info != null)
            {
                return(command.Info);
            }
            var analyzer = new LinqCommandAnalyzer();

            command.Info = analyzer.AnalyzeCommand(model, command);
            return(command.Info);
        }
Example #11
0
        object IQueryProvider.Execute(Expression expression)
        {
            // if session is null, it means that query is not executable - it should be used only to DEFINE a query and translate it to SQL
            // but not execute it. Example: DbView definition
            Util.Check(Session != null, "The query is not executable. Query: {0}", expression);
            var elemType = expression.Type.IsGenericType ? expression.Type.GenericTypeArguments[0] : typeof(object);
            var query    = new EntityQuery(this, elemType, expression);
            var command  = new LinqCommand(query, LinqCommandType.Select, LinqCommandKind.DynamicSql, null);
            var result   = Session.ExecuteLinqCommand(command);

            return(result);
        }
Example #12
0
 public LinqCommandInfo(LinqCommand command, QueryOptions options, LinqCommandFlags flags,
                        List <Type> entityTypes, string cacheKey, List <ParameterExpression> externalParameters,
                        List <LambdaExpression> includes)
 {
     CommandType        = command.CommandType;
     CommandKind        = command.Kind;
     Options            = options;
     Flags              = flags;
     EntityTypes        = entityTypes;
     CacheKey           = cacheKey;
     ExternalParameters = externalParameters;
     Includes           = includes;
 }
Example #13
0
 public LinqCommandInfo(LinqCommand command, QueryOptions options, LinqCommandFlags flags,
     List<Type> entityTypes, string cacheKey, List<ParameterExpression> externalParameters,
     List<LambdaExpression> includes)
 {
     CommandType = command.CommandType;
       CommandKind = command.Kind;
       Options = options;
       Flags = flags;
       EntityTypes = entityTypes;
       CacheKey = cacheKey;
       ExternalParameters = externalParameters;
       Includes = includes;
 }
Example #14
0
 private IDbCommand CreateLinqDbCommand(DataConnection connection, LinqCommand linqCommand, TranslatedLinqCommand translatedCommand)
 {
     var cmd = connection.DbConnection.CreateCommand();
       cmd.CommandType = CommandType.Text;
       cmd.CommandText = translatedCommand.Sql;
       foreach (var qParam in translatedCommand.Parameters) {
     var value = qParam.ReadValue(linqCommand.ParameterValues) ?? DBNull.Value;
     var dbParam = cmd.CreateParameter(); //DbModel.Driver.AddParameter(cmd,  //
     dbParam.ParameterName = qParam.Name;
     //Value and parameter may need some tweaking, depending on server type
     DbModel.LinqSqlProvider.SetDbParameterValue(dbParam, value);
     cmd.Parameters.Add(dbParam);
       }
       return cmd;
 }
Example #15
0
 public object ExecuteLinqCommand(EntitySession session, LinqCommand command)
 {
     var conn = GetLinqCommandConnection(session, command.Info.Flags);
       try {
     object result = command.CommandType == LinqCommandType.Select ?
       ExecuteLinqSelect(command, session, conn) :
       ExecuteLinqNonQuery(command, session, conn);
     ReleaseConnection(conn);
     return result;
       } catch (Exception dex) {
     ReleaseConnection(conn, inError: true);
     dex.AddValue(DataAccessException.KeyLinqQuery, command.QueryExpression);
     throw;
       }
 }
Example #16
0
        private void Preprocess(EntityModel model, LinqCommand command)
        {
            _model      = model;
            _command    = command;
            _parameters = new List <ParameterExpression>();
            //create parameters
            for (int i = 0; i < _command.Locals.Count; i++)
            {
                var prmExpr = _command.Locals[i];
                var prm     = prmExpr.NodeType == ExpressionType.Parameter ? (ParameterExpression)prmExpr : Expression.Parameter(prmExpr.Type, "@P" + i);
                _parameters.Add(prm);
            }
            var body = this.Visit(_command.Query.Expression);

            _command.Info.Lambda = Expression.Lambda(body, _parameters);
        }
Example #17
0
 public object ExecuteLinqCommand(EntitySession session, LinqCommand command)
 {
     object result;
       if(command.CommandType == LinqCommandType.Select && Cache != null && Cache.TryExecuteLinqQuery(session, command, out result))
     return result;
       result = Database.ExecuteLinqCommand(session, command);
       //If we are returning entities, cache them
       if(command.CommandType == LinqCommandType.Select) {
     var recs = result as IList<EntityRecord>;
     if(Cache != null && recs != null)
       Cache.CacheRecords(recs); //adds to sparse cache
       } else {
     // Update/Insert/Delete statemetns
     if (Cache != null && command.TargetEntity.CacheType != CacheType.None)
       Cache.Invalidate();
       }
       return result;
 }
Example #18
0
        public static void RunIncludeQueries(IEntitySession session, LinqCommand command, object mainQueryResult)
        {
            // initial checks if there's anything to run
            var resultShape = command.Info.ResultShape;

            if (mainQueryResult == null || resultShape == QueryResultShape.Object)
            {
                return;
            }
            var allIncludes = session.Context.GetMergedIncludes(command.Info.Includes);

            if (allIncludes.Count == 0)
            {
                return;
            }
            // Get records from query result
            var records = new List <EntityRecord>();

            switch (resultShape)
            {
            case QueryResultShape.Entity:
                records.Add(EntityHelper.GetRecord(mainQueryResult));
                break;

            case QueryResultShape.EntityList:
                var list = mainQueryResult as IList;
                if (list.Count == 0)
                {
                    return;
                }
                foreach (var ent in list)
                {
                    records.Add(EntityHelper.GetRecord(ent));
                }
                break;
            }//switch;
            // actually run the includes
            var entityType = records[0].EntityInfo.EntityType;
            var helper     = new IncludeQueryHelper(session, allIncludes);

            helper.RunIncludeQueries(entityType, records);
        }
Example #19
0
 private LinqCommandInfo AnalyzeCommand(EntityModel model, LinqCommand command)
 {
     _model   = model;
     _command = command;
     try {
         //include command type and options value into cache key
         AddCacheKey(command.CommandType);
         AnalyzeNode(_command.Query.Expression);
         _command.Locals = _locals;
         AddCacheKey(_options);
         var cacheKey = _cacheKeyBuilder.ToString();
         //Build command info
         var info = new LinqCommandInfo(command, _options, _flags, _entityTypes, cacheKey, _externalParams, _includes);
         info.ResultShape = GetResultShape(_command.Query.Expression.Type);
         return(info);
     } catch (Exception ex) {
         ex.Data["QueryExperssion"] = command.Query.Expression + string.Empty;
         throw;
     }
 }
Example #20
0
 public object ExecuteLinqSelect(LinqCommand linqCommand, EntitySession session, DataConnection conn)
 {
     var translCmd = GetTranslateLinqCommand(linqCommand);
       //Locks require ongoing transaction
       object result;
       var dbCommand = CreateLinqDbCommand(conn, linqCommand, translCmd);
       IList resultList = translCmd.ResultListCreator();
       ExecuteDbCommand(dbCommand, conn, DbExecutionType.Reader, reader => {
     while(reader.Read()) {
       var row = translCmd.ObjectMaterializer(reader, session);
       //row might be null if authorization filtered it out or if it is empty value set from outer join
       if(row != null)
     resultList.Add(row);
     }
     return resultList.Count;
       });
       //Post processor is extra selection op from the query (Fist,Single,Last)
       var postProcessor = translCmd.ResultsPostProcessor;
       if (postProcessor != null)
     result = postProcessor.ProcessRows(resultList);
       else
     result = resultList;
      return result;
 }
Example #21
0
 private void Preprocess(EntityModel model, LinqCommand command)
 {
     _model = model;
       _command = command;
       _parameters = new List<ParameterExpression>();
       //create parameters
       for (int i = 0; i < _command.Locals.Count; i++) {
     var prmExpr = _command.Locals[i];
     var prm = prmExpr.NodeType == ExpressionType.Parameter ? (ParameterExpression)prmExpr : Expression.Parameter(prmExpr.Type, "@P" + i);
     _parameters.Add(prm);
       }
       var body = this.Visit(_command.Query.Expression);
       _command.Info.Lambda = Expression.Lambda(body, _parameters);
 }
Example #22
0
 private static void ThrowTranslationFailed(LinqCommand command, string message, params object[] args)
 {
     var msg = StringHelper.SafeFormat(message, args) + "\r\n Query:" + command.ToString();
       var exc = new LinqTranslationException(msg, command);
       throw exc;
 }
Example #23
0
 // Looks up SQL query in query cache; if not found, builds SqlQuery object and saves in cache.
 private TranslatedLinqCommand GetTranslateLinqCommand(LinqCommand command)
 {
     var cmdInfo = command.Info;
       //Lookup in cache SQL query or build it
       var translCmd = this.DbModel.QueryCache.Lookup(cmdInfo.CacheKey);
       if(translCmd != null)
     return translCmd;
       //Build sqlQuery if not found
       var engine = new Vita.Data.Linq.Translation.LinqEngine(this.DbModel);
       translCmd = engine.Translate(command);
       // save in cache
       var canCache = !cmdInfo.Options.IsSet(QueryOptions.NoQueryCache) && !translCmd.Flags.IsSet(LinqCommandFlags.NoQueryCache);
       if (canCache)
     DbModel.QueryCache.Add(cmdInfo.CacheKey, translCmd);
       return translCmd;
 }
Example #24
0
 public bool TryExecuteLinqQuery(EntitySession session, LinqCommand command, out object result)
 {
     result = null;
       if(!Settings.CacheEnabled || session.CacheDisabled || command.Info.Options.IsSet(QueryOptions.NoEntityCache))
     return false;
       if(_fullSetCache.TryExecuteDynamicQuery(session, command, out result)) {
     return true;
       }
       return false;
 }
Example #25
0
 public LinqCommandEventArgs(IEntitySession session, LinqCommand command)
     : base(session)
 {
     Command = command;
 }
Example #26
0
 internal void OnExecutedQuery(EntitySession session, LinqCommand command)
 {
     if (ExecutedQuery != null)
     ExecutedQuery(session, new LinqCommandEventArgs(session, command));
 }
Example #27
0
 // analyzes external values and creates db parameters
 private List<LinqCommandParameter> BuildParameters(LinqCommand command, TranslationContext context)
 {
     var sqlProvider = _dbModel.LinqSqlProvider;
       var parameters = new List<LinqCommandParameter>();
       foreach (var extValue in context.ExternalValues) {
     if (extValue.SqlUseCount == 0)
       extValue.SqlUse = ExternalValueSqlUse.NotUsed;
     else
       _dbModel.LinqSqlProvider.CheckQueryParameter(extValue);
     switch (extValue.SqlUse) {
       case ExternalValueSqlUse.NotUsed:
         continue; //next value
       case ExternalValueSqlUse.Literal:
         // We cannot use this value as a parameter (ex: list/array of values with Contains() method);
         // in this case we transform it into literal value - it will be embedded into SQL directly.
         // The query becomes non-cacheable (because of this embedded literal)
         var paramReadValue = BuildParameterValueReader(command.Info.Lambda.Parameters, extValue.SourceExpression);
         extValue.LiteralValue = paramReadValue(context.Command.ParameterValues);
         break;
       case ExternalValueSqlUse.Parameter:
         var valueReader = BuildParameterValueReader(command.Info.Lambda.Parameters, extValue.SourceExpression);
         var dbParamName = _dbModel.LinqSqlProvider.GetParameterName("P" + parameters.Count);
         extValue.LinqParameter = new LinqCommandParameter(dbParamName, parameters.Count, extValue.SourceExpression.Type, valueReader);
         parameters.Add(extValue.LinqParameter);
         break;
     }//switch
       }//foreach extValue
       return parameters;
 }
Example #28
0
        private TranslatedLinqCommand TranslateNonQuery(LinqCommand command)
        {
            LinqCommandPreprocessor.PreprocessCommand(_dbModel.EntityApp.Model, command);
              var rewriterContext = new TranslationContext(_dbModel, command);
              var cmdInfo = command.Info;
              // convert lambda params into an initial set of ExternalValueExpression objects;
              foreach(var prm in cmdInfo.Lambda.Parameters) {
            var inpParam = new ExternalValueExpression(prm);
            rewriterContext.ExternalValues.Add(inpParam);
              }
              //Analyze/transform base select query
              var exprChain = ExpressionChain.Build(cmdInfo.Lambda.Body);
              var selectExpr = BuildSelectExpression(exprChain, rewriterContext);
              // Analyze external values (parameters?), create DbParameters
              var cmdParams = BuildParameters(command, rewriterContext);
              var flags = command.Info.Flags;
              // If there's at least one parameter that must be converted to literal (ex: value list), we cannot cache the query
              bool canCache = !rewriterContext.ExternalValues.Any(v => v.SqlUse == ExternalValueSqlUse.Literal);
              if (!canCache)
            flags |= LinqCommandFlags.NoQueryCache;

              // !!! Before that, everyting is the same as in TranslateSelect
              var targetEnt = command.TargetEntity;
              var targetTableInfo = _dbModel.GetTable(targetEnt.EntityType);
              TableExpression targetTable;
              bool isSingleTable = selectExpr.Tables.Count == 1 && selectExpr.Tables[0].TableInfo == targetTableInfo;
              if(isSingleTable) {
            targetTable = selectExpr.Tables[0];
              } else
            targetTable = _translator.CreateTable(targetEnt.EntityType, rewriterContext);
              var commandData = new NonQueryLinqCommandData(command, selectExpr, targetTable, isSingleTable);
              // Analyze base query output expression
              var readerBody = selectExpr.Reader.Body;
              switch(command.CommandType) {
            case LinqCommandType.Update:
            case LinqCommandType.Insert:
              Util.Check(readerBody.NodeType == ExpressionType.New, "Query for LINQ {0} command must return New object", commandData.CommandType);
              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 MemberKind.Column:
                var col = _translator.CreateColumn(targetTable, memberName, rewriterContext);
                commandData.TargetColumns.Add(col);
                commandData.SelectOutputValues.Add(outValues[i]);
                break;
              case MemberKind.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.CreateColumn(targetTable, pkMember.MemberName, rewriterContext);
                commandData.TargetColumns.Add(col2);
                commandData.SelectOutputValues.Add(outValues[i]);
                break;
              default:
                Util.Throw("Property cannot be used in the context: {0}.", memberName);
                break;
            }
              }
              break;
            case LinqCommandType.Delete:
              commandData.SelectOutputValues.Add(readerBody); //should return single value - primary key
              break;
              }
              // Build SQL
              var sqlBuilder = new SqlBuilder(_dbModel);
              var sqlStmt = sqlBuilder.BuildNonQuery(commandData);
              var sqlTemplate = sqlStmt.ToString();
              var defaultSql = FormatSql(sqlTemplate, cmdParams);
              return new TranslatedLinqCommand(sqlTemplate, defaultSql, cmdParams, flags);
        }
Example #29
0
 private TranslatedLinqCommand TranslateSelect(LinqCommand command)
 {
     LinqCommandPreprocessor.PreprocessCommand(_dbModel.EntityApp.Model, command);
       var context = new TranslationContext(_dbModel, command);
       var cmdInfo = command.Info;
       // convert lambda params into an initial set of ExternalValueExpression objects;
       foreach (var prm in cmdInfo.Lambda.Parameters) {
     var inpParam = new ExternalValueExpression(prm);
     context.ExternalValues.Add(inpParam);
       }
       //Analyze/transform query expression
       var exprChain = ExpressionChain.Build(cmdInfo.Lambda.Body);
       var selectExpr = BuildSelectExpression(exprChain, context);
       // Analyze external values (parameters?), create DbParameters
       var commandParams = BuildParameters(command, context);
       // If there's at least one parameter that must be converted to literal (ex: value list), we cannot cache the query
       bool canCache = !context.ExternalValues.Any(v => v.SqlUse == ExternalValueSqlUse.Literal);
       if (!canCache)
     command.Info.Flags |= LinqCommandFlags.NoQueryCache;
       //Build SQL, compile object materializer
       var sqlBuilder = new SqlBuilder(_dbModel);
       var sqlStatement = sqlBuilder.BuildSelect(selectExpr);
       // Parameters are represented as {2}, {3}, etc.
       // Braces in string literals are escaped and are represented as '{0}' and '{1}'
       var sqlTemplate = sqlStatement.ToString();
       var sql = FormatSql(sqlTemplate, commandParams);
       var objMaterializer = CompileObjectMaterializer(context);
       var outType = context.CurrentSelect.Reader.Body.Type;
       var resultListCreator = ReflectionHelper.GetCompiledGenericListCreator(outType);
       //check if we need to create implicit result set processor
       if (selectExpr.ResultsProcessor == null) {
     var returnsResultSet = typeof(IQueryable).IsAssignableFrom(cmdInfo.Lambda.Body.Type);
     if (!returnsResultSet)
       selectExpr.ResultsProcessor = QueryResultsProcessor.CreateFirstSingleLast("First", outType);
       }
       var sqlQuery = new TranslatedLinqCommand(sqlTemplate, sql, commandParams, command.Info.Flags,
           objMaterializer, selectExpr.ResultsProcessor, resultListCreator);
       return sqlQuery;
 }