2013-08-08 2 views
3

У меня есть 2 метода, как показано ниже:Как правильно использовать SqlDataReader?

internal static SqlDataReader SelectData(string sql) 
{ 
    using (var sqlConnection = new SqlConnection(Constant.ConnectionString)) 
    { 
     sqlConnection.Open(); 
     var sqlCommand = new SqlCommand(sql, sqlConnection); 
     var dataReader = sqlCommand.ExecuteReader(); 
     return dataReader; 
    } 
} 

============

И используя этот метод, как:

var dataReader = SelectData(---some sql ---); 

private void AddData(dataReader) 
{ 
    while (dataReader.Read()) 
    { 
     Employee e = new Employee(); 
     e.FirstNamei = dataReader["Name"].ToString(); 
    } 

    dataReader.Close(); 
} 

Я знаю, что мы можем объединить этот два метода, но я смотрю на лучший способ написать это, ИЛИ это может вызвать некоторые проблемы?

+2

Вы упомянули, что используете второй метод во втором, но это неверно. Оба метода кажутся несвязанными друг с другом, поэтому ваш вопрос все еще неясен. Btw, [** never ** использовать пустые 'catch'-blocks] (http://stackoverflow.com/a/1234364/284240). –

+0

@TimSchmelter .. Правильно .. Я отредактировал .. – Tech

+0

Почему бы не использовать Enterprise Libraries для доступа к данным? –

ответ

5

Фактически вы фактически оставляете себя немного открытым. Вы действительно хотите, чтобы написать это:

using (SqlConnection cnn = new SqlConnection(cnnString)) 
using (SqlCommand cmd = new SqlCommand(sql, cnn)) 
{ 
    // use parameters in your SQL statement too, so you can do this 
    // and protect yourself from SQL injection, so for example 
    // SELECT * FROM table WHERE field1 = @parm1 
    cmd.Parameters.AddWithValue("@parm1", val1); 

    cnn.Open(); 
    using (SqlDataReader r = cmd.ExecuteReader()) 
    { 

    } 
} 

потому, что вам нужно сделать уверены эти объекты получить расположены. Далее, перейдя в этом направлении, вам не нужно dataReader.Close(). Он будет вызван, когда он автоматически будет удален оператором using.

Теперь оберните эту сборку инструкций внутри try...catch, и вы находитесь в бизнесе.

+0

Я просто пытался его реорганизовать .. так что я могу использовать метод, как 'SelectData' везде. Что вы дали, это отличный рабочий код. – Tech

+0

Для большей ясности первый набор фигурных скобок не нужен. используя (SqlConnection cnn = n .....) используя (SqlCommand cmd = n .....) { // Код } Просто экономит на столько гнездования. Использование заявлений может возвращаться назад – Hawxby

+0

@Hawxby, я не уверен, что я следую. –

2

Пара вещей

1) Так как вы закрываете соединение на SelectData, dataReader должен взорвать на AddData, поскольку она требует открытого соединения

2) AddData не должны закрывать DataReader как он не открывал.

3) Может быть, вы прячетесь код, но я не вижу, что вы используете Employee экземпляр, созданный на AddData

+0

Это значит, что datareader пуст, когда я обращаюсь к методу AddData? – Tech

+0

@Ratan: не пусто, он должен выдать сообщение об ошибке, поскольку соединение больше не работает. –

+0

ok..point принят. – Tech

0

Технически, первый метод будет правильным, если бы вы сделали

sqlCommand.ExecuteReader(CommandBehavior.CloseConnection); 

Тогда , ваш клиент закроет читателя, и ваше соединение также будет закрыто.

Второй пример также был бы правильным, если бы вы не закрыли его внутри. Нет никакого преступника, передающего читателю метод, чтобы его повторить. но его нужно контролировать, откуда он был создан. Как вы его открываете и распоряжаетесь - это другой вопрос.

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