/// <summary>
        /// Executes this command against the specified database connection and returns the number of rows affected.
        /// </summary>
        public int Execute(DBConnection cn)
        {
            if (conditions.Count == 0)
            {
                throw new ApplicationException("Executing an inline delete command with no parameters in the where clause is not allowed.");
            }
            var cmd = cn.DatabaseInfo.CreateCommand(timeout);

            var sb = new StringBuilder("DELETE FROM ");

            sb.Append(tableName);
            sb.Append(" WHERE ");

            var          paramNumber = 0;
            const string and         = " AND ";

            foreach (var condition in conditions)
            {
                condition.AddToCommand(cmd, sb, cn.DatabaseInfo, InlineUpdate.GetParamNameFromNumber(paramNumber++));
                sb.Append(and);
            }

            sb.Remove(sb.Length - and.Length, and.Length);

            cmd.CommandText = sb.ToString();

            return(cn.ExecuteNonQueryCommand(cmd));
        }
        /// <summary>
        /// Executes this command using the specified database connection to get a data reader and then executes the specified
        /// method with the reader.
        /// </summary>
        public void Execute(DBConnection cn, Action <DbDataReader> readerMethod)
        {
            // NOTE SJR: Say a single insert statement gets executed 1000 times. This will generate the same
            // duplicate string in memory 1000 times. But, we wouldn't want to intern the strings because
            // those strings would never leave the pool and effectively be leaked. I think per maybe, a transaction,
            // we should intern strings ourselves. We could either generate the string again, but then dump it if
            // it's a duplicate (easy), or use the inputs to determine if WOULD generate the same string, and instead
            // pull the one already-generated out of the cache (hard).
            var command = cn.DatabaseInfo.CreateCommand(timeout);

            var sb = new StringBuilder("SELECT");

            if (cacheQueryInDatabase && cn.DatabaseInfo.QueryCacheHint.Any())
            {
                sb.Append(" ");
                sb.Append(cn.DatabaseInfo.QueryCacheHint);
            }

            sb.Append(" ");
            sb.Append(StringTools.ConcatenateWithDelimiter(", ", selectExpressions));
            sb.Append(" ");
            sb.Append(fromClause);

            if (conditions.Any())
            {
                sb.Append(" WHERE ");

                var first       = true;
                var paramNumber = 0;
                foreach (var condition in conditions)
                {
                    if (!first)
                    {
                        sb.Append(" AND ");
                    }
                    first = false;
                    condition.AddToCommand(command, sb, cn.DatabaseInfo, InlineUpdate.GetParamNameFromNumber(paramNumber++));
                }
            }

            if (orderByClause != "")
            {
                sb.Append(" ");
                sb.Append(orderByClause);
            }

            command.CommandText = sb.ToString();

            cn.ExecuteReaderCommand(command, readerMethod);
        }