#c# #asp.net #sql
#c# #asp.net #sql
Вопрос:
Мне нужно выполнить несколько запросов внутри одной функции, нужно ли мне создавать новое SqlConnection для каждого? Или наличие одного соединения, но разных SqlCommands тоже работает?
Спасибо,
РЕДАКТИРОВАТЬ: будет ли это работать?
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(query1, conn))
{
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd = new SqlCommand(query2, conn))
{
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd = new SqlCommand(query3, conn))
{
cmd.ExecuteNonQuery();
}
}
Комментарии:
1. Лучше покажите нам свой код, тогда мы сможем предложить вам лучшее.
2. я видел ваш другой вопрос, не передавайте значения в sql statemetns как встроенные, это может привести к sql-инъекции..
3. если вы помещаете все внутрь с помощью, вам не нужно избавляться от этого. SqlConnection и SqlCommand реализуют IDisposable. Удалить «conn. Close(); продолжение. Dispose(); cmd. Dispose();» 😀
Ответ №1:
Использование документации MDSN в качестве основы:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql1 = "SELECT ID,FirstName,LastName FROM VP_PERSON";
string sql2 = "SELECT Address,City,State,Code FROM VP_ADDRESS";
using (SqlCommand command = new SqlCommand(sql1,connection))
{
//Command 1
using (SqlDataReader reader = command.ExecuteReader())
{
// reader.Read iteration etc
}
} // command is disposed.
using (SqlCommand command = new SqlCommand(sql2,connection))
{
//Command 1
using (SqlDataReader reader = command.ExecuteReader())
{
// reader.Read iteration etc
}
} // command is disposed.
// If you don't using using on your SqlCommands you need to dispose of them
// by calling command.Dispose(); on the command after you're done.
} // the SqlConnection will be disposed
Комментарии:
1. Спасибо за помощь, я просто хотел узнать, что я могу поместить внутрь части using (SqlCommand command = new …), просто команды query execute и dispose?
2. Поместите в свой SqlDataReader, используйте его, а затем утилизируйте. Или, еще лучше, поместите SqlDataReader внутри using .
Ответ №2:
Не имеет значения, каким путем вы идете.
SqlConnections
объединяются операционной системой в пул. Вы могли бы буквально открывать и закрывать соединение тысячи раз подряд и не понести никакого ущерба производительности или другого ущерба.
Как это работает, так это:
- Приложение выполняет запрос на создание подключения к БД (
var c = new SqlConnection(...)
) - Пул подключений операционной системы проверяет, есть ли у него незанятое соединение. Если это произойдет, вы получите ссылку на это. Если нет, то запускается новый.
- Приложение указывает, что подключение завершено (
c.Dispose()
) - Операционная система сохраняет соединение открытым в течение определенного периода времени на случай, если ваше приложение или другое попытается создать другое соединение с тем же ресурсом.
- Если это соединение остается незанятым до истечения периода ожидания, тогда ОС окончательно закрывается и освобождается.
Вот почему при первом подключении к базе данных может потребоваться секунда для запуска, прежде чем команды смогут быть обработаны. Однако, если вы закроете его и снова откроете, соединение будет доступно немедленно. Дополнительная информация здесь:http://msdn.microsoft.com/en-us/library/8xx3tyca (v = против 110).aspx
Теперь, что касается вашего кода, вообще говоря, вы открываете 1 SqlConnection каждый раз, когда выполняете вызов SqlCommand ; однако, вполне приемлемо / разумно выполнять несколько вызовов SqlCommand внутри одного блока в предложении SqlConnection using .
Просто имейте в виду, что вы не хотите, чтобы объект SqlConnection зависал в вашем коде дольше, чем это абсолютно необходимо. Это может привести к множеству потенциальных проблем, особенно если вы занимаетесь веб-разработкой. Это означает, что для вашего кода гораздо лучше открывать и закрывать 100 объектов SqlConnection в быстрой последовательности, чем удерживать этот объект и передавать его с помощью различных методов.
Ответ №3:
Наличие одного SqlConnection
и многих SqlCommands
запросов будет работать нормально, однако вы должны убедиться, что вы избавились от любых SqlDataReaders
, возвращенных из предыдущих команд, прежде чем пытаться запустить дополнительные команды.
using (SqlConnection conn = new SqlConnection())
{
conn.Open()
using (SqlCommand cmd = new SqlCommand("SELECT myrow FROM mytable", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Handle first resultset here
}
}
using (SqlCommand cmd = new SqlCommand("SELECT otherrow FROM othertable", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Handle second resultset here
}
}
}
В качестве альтернативы вы могли бы объединить свои команды в один пакет и вместо этого обработать несколько наборов результатов, например:
using (SqlConnection conn = new SqlConnection())
{
conn.Open()
using (SqlCommand cmd = new SqlCommand("SELECT myrow FROM mytable; SELECT otherrow FROM othertable", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Handle first resultset here, and then when done call
if (reader.NextResult())
{
// Handle second resultset here
}
}
}
}
Когда вы обрабатываете множество наборов результатов, вы обнаружите, что объединение запросов, подобных этому, может значительно повысить производительность, однако это достигается ценой дополнительной сложности вашего вызывающего кода.
Комментарии:
1. Я новичок в asp.net и мы не были представлены SqlDataReaders. В настоящее время я использую только SqlConnection, затем создаю SqlCommand, комбинируя запрос и новое соединение, и после этого использую либо SqlDataAdapter для извлечения данных, либо ExecuteNonQuery. Должен ли я вместо этого просто обеспечить удаление соединения и команды?
2. @QPTR я не использовал
SqlDataAdapter
раньше и поэтому не знаю, но я полагаю, что вам придется избавиться отSqlDataAdapter
, прежде чем вы сможете запустить другой запрос. Извините, я не знаю этого наверняка, хотя кто-то более сведущий в этой области должен быть в состоянии вам помочь.3. @qptr, использование которого автоматически выполняется за вас, не нужно делать ничего дополнительного.
4. Круто, я просто попробую поместить свой код выполнения запроса внутрь using, большое спасибо за помощь!
Ответ №4:
Откройте только одно SqlConnection
Используйте keyworkd с помощью, поскольку это автоматически удалит соединение.
Если вы открываете соединение для каждого из них, у него могут возникнуть проблемы с производительностью.
Пример:
using (SqlConnection con = new SqlConnection(connectionString))
{
//
// Open the SqlConnection.
//
con.Open();
//
// The following code shows how you can use an SqlCommand based on the SqlConnection.
//
using (SqlCommand command = new SqlCommand("SELECT TOP 2 * FROM Dogs1", con))
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0} {1} {2}",
reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
}
}
}
Еще один пример:
public DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection("your connection here")
{
con.Open();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "your stored procedure here";
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
}
return dt;
}
Комментарии:
1. Могу ли я использовать это таким образом: ‘SqlConnection con = new SqlConnection(ConnectionString); con. Открыть(); строка cmdText = «запрос» SqlCommand cmd = новая SqlCommand(cmdText, con); cmd. ExecuteNonQuery(); cmd. Dispose(); против. Close(); кон. Dispose();’ Затем создаем другое соединение и повторяем процесс. Я новичок в asp.net и не понимаю, как использовать DataReaders.
2. QPTR, не создавайте другой connectoin, это может привести к снижению производительности в любом случае, почему вы хотите открыть другое соединение, у вас уже есть открытое соединение с вашей базой данных, вы хотите открыть несколько баз данных.
3. Хорошо, тогда я могу использовать ваш способ, но внутри части using (SqlCommand = new …) просто добавьте код команды execute и dispose вместо использования reader, я действительно не понимаю их использования. Спасибо за помощь!
4. @QPTR, да, это круто, если это хранимая процедура или sql, который вставляет, вы можете использовать nonexecute , если он получает какие-либо данные типа select, вам нужно сказать execute query , SLQDataAdapter используется для выполнения и получения результатов в datatable.
5. я добавил для вас еще один пример
Ответ №5:
Исключительно в качестве альтернативы операторам using:
SqlConnection con = new SqlConnection(myConnectionString);
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = @"SELECT [stuff] FROM [tableOfStuff]";
con.Open();
SqlDataReader dr = null;
try
{
dr = cmd.ExecuteReader();
while(dr.Read())
{
// Populate your business objects/data tables/whatever
}
}
catch(SomeTypeOfException ex){ /* handle exception */ }
// Manually call Dispose()...
if(con != null) con.Dispose();
if(cmd != null) cmd.Dispose();
if(dr != null) dr.Dispose();
Основное различие между этим и инструкциями using заключается в том, что это позволит вам более аккуратно обрабатывать исключения.
Комментарии:
1. Спасибо за ответ, в данный момент я не использую SqlDataReader, но я прочитаю об этом, как только закончу это задание. Спасибо за пример!
2. Обратите внимание, что выполнение этого таким образом означает, что при возникновении каких-либо ошибок в скрипте все будет удалено не так, как вы ожидаете.