2015-11-27 2 views
0

Я пытаюсь извлечь запись из базы данных с помощью хранимой процедуры, но возвращает null в SqlDataReader объекте.получить запись из БД с помощью хранимой процедуры в C#

Вот мой код:

public Buybest_Liberary.Data.UserManagement getUser(string email) 
{ 
    Buybest_Liberary.Data.UserManagement obj = new Buybest_Liberary.Data.UserManagement(); 
    string conString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ahmadshair\Documents\Buybest.mdf;Integrated Security=True;Connect Timeout=30"; 

    SqlConnection connection = new SqlConnection(conString); 
    connection.Open(); 

    SqlCommand _cmd = new SqlCommand("getUserRecord", connection); 
    _cmd.CommandType = CommandType.StoredProcedure; 
    _cmd.Parameters.Add("@Email", SqlDbType.NVarChar).Value = email; 

    SqlDataReader dr = _cmd.ExecuteReader(); 

    if (dr.HasRows) 
    { 
     obj.UId = Convert.ToInt32(dr[0]); 
     obj.Email = dr[1].ToString(); 
     obj.Password = dr[2].ToString(); 
    } 

    return obj; 
} 
+0

Какое определение 'getUserRecord'? Вы действительно уверены, что он возвращает некоторые данные? –

ответ

5

Перед обращением к данным необходимо позвонить dr.Read()! Также: положить одноразовые предметы (SqlConnection, SqlCommand, SqlDataReader) в using(..) { ... } блоков, чтобы обеспечить надлежащую утилизацию:

public Buybest_Liberary.Data.UserManagement getUser(string email) 
{ 
    Buybest_Liberary.Data.UserManagement obj = new Buybest_Liberary.Data.UserManagement(); 

    // You should read the connection string from a config file 
    // don't specify it explicitly in code! 
    string conString = ConfigurationManager.ConnectionStrings["-your-connection-string-name-here-"].ConnectionString; 

    using (SqlConnection connection = new SqlConnection(conString)) 
    using (SqlCommand _cmd = new SqlCommand("getUserRecord", connection)) 
    { 
     _cmd.CommandType = CommandType.StoredProcedure; 
     _cmd.Parameters.Add("@Email", SqlDbType.NVarChar).Value = email; 

     connection.Open(); 

     using (SqlDataReader dr = _cmd.ExecuteReader()) 
     { 
      // the SqlDataReader could return *multiple* rows - how are you 
      // going to deal with that? Create an object for each row of data 
      // and add them to a list to return? 
      while (dr.Read()) 
      { 
       obj.UId = Convert.ToInt32(dr[0]); 
       obj.Email = dr[1].ToString(); 
       obj.Password = dr[2].ToString(); 
      } 

      dr.Close(); 
     } 

     connection.Close(); 
    } 

    return obj; 
} 

Кроме того: что делать, если хранимая процедура возвращает мультипликатор строк данных? Вам нужно как-то справиться с этим, тоже

+0

Кроме того, не печатайте код строки подключения. прочитайте его из файла конфигурации. Не нужно вызывать dr.Close() и connection.Close(), потому что dr и соединение заключены в использование блоков –

+0

@ JesúsLópez: согласен - строка подключения была скопирована из вопроса - не моя. И да - нет * строгого * нужно называть 'dr.Close()' или 'connection.Close()' - но это тоже не больно - я предпочитаю быть ** явным **. –

+0

это в порядке. Однако я считаю, что лучше научить лучших практик новичкам, а не просто отвечать на прямой вопрос. –

4

Если я не ошибаюсь, вам не хватает dr.Read() для извлечения первой записи.

2

HasRows просто говорит вам, есть ли какие-либо строки для чтения, тогда как Read() продвигает внутренний курсор к следующей строке в данных и, кстати, возвращает False, если есть больше нет строк для чтения или True, если имеется еще одна строка. Нам нужно dr.read()

Смежные вопросы