SQL DataReader отсутствует строка в цикле - PullRequest
2 голосов
/ 20 ноября 2008

При запуске следующего кода он пропускает одну строку. Когда я делаю файлы. Счет говорит, что есть 4 строки, но для 4-й строки нет никаких данных. Когда я запускаю хранимую процедуру из SQL Manager, она возвращает все 4 строки и все данные. Любая помощь?

            List<File> files = new List<File>();
            SqlConnection active_connection = new SqlConnection(m_connection_string);
            SqlCommand cmd = new SqlCommand();
            SqlDataReader dr = null;

            try
            {
                active_connection.Open();
                cmd.Connection = active_connection;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "dalsp_Select_Organization_Files";

                SqlParameter param;

                param = cmd.Parameters.Add("@p_organization_guid", SqlDbType.UniqueIdentifier);
                param.Value = new Guid(organization_guid);

                param = cmd.Parameters.Add("@p_file_type", SqlDbType.NVarChar, 50);
                param.Value = file_type;

                dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

                if (dr.HasRows)                    
                {                    
                    while (dr.Read())
                    {
                        File file = new File();
                        file.OrganizationGuid = dr["OrganizationGuid"].ToString();
                        file.FileGuid = dr["FileGuid"].ToString();
                        file.FileLocation = dr["FileLocation"].ToString();
                        file.FileName = dr["FileName"].ToString();
                        file.FileType = (FileTypeEnum)Enum.Parse(typeof(FileTypeEnum), dr["FileType"].ToString());
                        file.FileExtension = dr["FileExtension"].ToString();
                        file.FileDescription = dr["FileDescription"].ToString();
                        file.ThumbnailPath = dr["ThumbnailPath"].ToString();
                        files.Add(file);
                    }       
                }
                dr.Close();
                dr = null;

                active_connection.Close();
                cmd = null;

            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (active_connection.State != ConnectionState.Closed)
                {
                    active_connection.Close();
                    active_connection.Dispose();
                }
            }

            return files;

Ответы [ 4 ]

5 голосов
/ 20 ноября 2008

Если вы говорите, что в вашей коллекции файлов 4 элемента, но 4 элемента не содержат значения, что вы подразумеваете под этим? Это значение равно null, у объекта нет данных или он выбрасывает индекс вне диапазона исключений?

Вы делаете файлы [4] или что-то вроде следующего?

for(int x = 1; x < files.length; x++)
{
     files[x]
}

Это не сработает. Помните индексирование на основе 0 в C #.

В качестве дополнительного примечания вы можете покончить со своими попытками поймать статистику, выполнив что-то вроде:

using (SqlConnection connection = new SqlConnection(conn_string))
{
    connection.Open();
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM MyTable", connection))
    {
         using (SqlDataReader dr = cmd.ExecuteReader())
         {
             return result;
         }
    }
}

Оператор использования гарантирует удаление (и, следовательно, закрытие) считывателя и подключение.

2 голосов
/ 20 ноября 2008

Вы должны отказаться от «if (dr.HasRows)», все, что он делает, это дублирует проверку в цикле while.

Вы никогда не должны вызывать Close для соединения, и при этом вы не должны устанавливать его в null. Вместо этого вы должны заключить соединение в блок «using» следующим образом:

using (SqlCommand cmd = new SqlCommand()) {
   //use the connection
}

То же самое можно сказать для читателя данных и команды SQL.

Этот следующий бит ничего не делает, удалите его.

  catch (Exception) { throw; }            
1 голос
/ 20 ноября 2008

Код выглядит правильно для меня. Я думаю, что вы определенно захотите пройтись по отладчику, чтобы увидеть, сколько строк возвращается из ExecuteReader. У меня есть один комментарий: «if (dr.HasRows)» несколько избыточен, поскольку «while (dr.Read ())» даст вам тот же эффект.

Другой вопрос, который у меня возникнет, - знаете ли вы, пропустили ли вы первую или последнюю запись?

Brian

1 голос
/ 20 ноября 2008

Вы пытались пройти через это в отладчике и проверять параметры команды перед тем, как запускать программу чтения? Получаете ли вы те же значения в наборе результатов, что и при запуске sproc direct на sql?

Я могу ошибаться, потому что есть несколько способов сделать это, но что-то выглядит немного странно в том, как вы добавляете параметры в команду.

Я обычно использую шаблон больше как:

SqlParameter param = new SqlParameter();  
// set param stuff - here or in ctor   
cmd.Parameters.Add(param);  

В основном о том, что работает для вас ....

В большинстве случаев у меня возникали проблемы с sprocs, когда я изменял параметры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...