SQLConnection с оператором Using, вызывающим из него SQLDataReader? - PullRequest
3 голосов
/ 17 декабря 2010

Просто хочу убедиться, что это лучший способ для вызова соединения и получения данных из базы данных, или мне следует каким-то образом вызывать устройство чтения данных вне оператора using?(для того, чтобы соединение закрылось быстрее?) или есть что-то, что вы бы лично изменили на это?

using (SqlConnection cn = new SqlConnection(connStr))
        {
            using (SqlCommand cm = new SqlCommand(connStr, cn))
            {  
                cm.CommandType = CommandType.StoredProcedure;
                cm.CommandText = "GetExchRatesByDate";
                cm.Parameters.Add("@Date", SqlDbType.VarChar).Value = txtStartDate.Text;
                cn.Open();
                SqlDataReader dr = cm.ExecuteReader();

                while (dr.Read())
                {
                    firstName = (string)dr["GivenName"];
                    lastName = (string)dr["sn"];;
                }
                dr.Close();
            }
        }

Ответы [ 5 ]

5 голосов
/ 17 декабря 2010

Мало того, что вы не можете сделать вызов SqlDataReader вне оператора using, поскольку все объявленные в переменных будут удалены, и вам нужно открытое соединение для чтения данных, вам лучше написать объект, который будет или даже список вашего объекта.

public class MyObject {
    public string FirstName { get; set; }
    public string Surname { get; set; }
}

public IEnumerable<MyObject> GetObjects() {
    ICollection<MyObject> myObjects = new List<MyObject>();

    using (SqlConnection cn = new SqlConnection(connStr))
    {
        using (SqlCommand cm = new SqlCommand(connStr, cn))
        {  
            cm.CommandType = CommandType.StoredProcedure;
            cm.CommandText = "GetExchRatesByDate";
            cm.Parameters.Add("@Date", SqlDbType.VarChar).Value = txtStartDate.Text;
            cn.Open();

            using(SqlDataReader dr = cm.ExecuteReader()) 
                while (dr.Read()) {
                    MyObject myObject = new MyObject();
                    myObject.FirstName = (string)dr["GivenName"];
                    myObject.Surname = (string)dr["sn"];
                    myObjects.Add(myObject);
                }
        }
    }
    return myObjects;
}
5 голосов
/ 17 декабря 2010

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

Соединение будет закрываться достаточно быстро, как у вас, и даже не «закроется».Он будет возвращен в пул соединений (при условии, что вы его используете).Поскольку это, вероятно, так, вам не нужно беспокоиться о том, как быстро соединение закрывается в этом контексте, так как другие части приложения, нуждающиеся в соединении, будут получать доступную из пула.Это предполагает, что у вас нет приложения с действительно высоким трафиком, это может стать важным в этом сценарии, но это много, много, много одновременных пользователей, и вы можете решить эту проблему, увеличив число подключений в пуле.,

Крис также поднял хорошую мысль: это должно быть в выражении использования:

  SqlDataReader dr = cm.ExecuteReader();

                while (dr.Read())
                {
                    firstName = (string)dr["GivenName"];
                    lastName = (string)dr["sn"];;
                }
                dr.Close();

В этом случае, если ваш читатель выдает исключение, он никогда не получит1008 *, поэтому он останется открытым намного дольше, чем нужно (возможно, даже на весь срок службы приложения).

Считыватель данных

2 голосов
/ 17 декабря 2010

В хранилище данных реализован IDisposable, поэтому его также следует заключить в условие using Все остальное выглядит хорошо.

1 голос
/ 17 декабря 2010

Другие рассмотрели этот вопрос, но мне нравится использовать еще одну вещь: AddWithValue:

cm.Parameters.Add("@Date", SqlDbType.VarChar).Value = txtStartDate.Text;

можно записать как:

cm.Parameters.AddWithValue("@Date", txtStartDate.Text);
0 голосов
/ 17 декабря 2010

Я хотел бы рассмотреть вопрос о подключении SQLConnection к заводскому методу.(если это называется load)

Также у меня не было бы цикла while вокруг dr.Read. Вы ожидаете только одного ответа, так что же происходит, когда нет результатов или много результатов ????Не слишком уверен, нравится ли мне приведение, но, вероятно, все в порядке.

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

Ваши заявления об использовании выглядят хорошо для меня.

...