SQL может обрабатывать несколько соединений одновременно. Однако вы, скорее всего, будете работать одновременно с двумя клиентами, и они будут использовать одно соединение, а не два отдельных соединения. Это плохо # 1.
SQL Server делает фантастическую работу по объединению соединений - и я полагаю, что другие БД имеют схожие возможности. В таком мире вы не должны пытаться хранить и повторно использовать какие-либо объекты, связанные с данными, но создавать их по мере необходимости, а когда SQL видит, что вы используете соединение, которое оно создано до и после освобождения, оно Я буду использовать это. Вам не нужно делать ничего странного, чтобы получить эту функциональность.
Имея это в виду, ваши статические объекты должны в основном уходят, и ваш метод SQLInject может выглядеть примерно так:
public static void SqlInject(string query, string dataBase)
{
var connectionString =
System
.Configuration
.ConfigurationManager
.ConnectionStrings["conProject"]
.ConnectionString;
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
}
Обратите внимание, что вам не придется беспокоиться о закрытии соединения по себе; блоки using
обрабатывают расположение открытых активных объектов. Это в значительной степени то, как люди делают прямые SQL
от c#
. Кстати, ни ваш код, ни мой не используют аргумент dataBase. Может быть, вы должны отредактировать базовую строку соединения с ней?
Но подождите - есть еще!
Сказав все это, и поскольку вы подняли озабоченность по поводу безопасности, вы должны знать, что это не безопасный код вообще - ваш или мой. SqlInject, вероятно, является хорошим именем, потому что он позволяет почти что угодно в аргументе query
(который, BTW, если вы делаете ExecuteNonQuery, то, возможно, query
- нехорошее имя).
Вы гораздо лучше разрешаете аргументы в библиотеке известных утверждений (возможно, хранимых процедур), проверяя эти аргументы и применяя смягчение атаки SQL Injection для параметризации ваших известных утверждений (найдите эту фразу, и вы найдете изобилие примеров и рекомендаций).
Просто для yuks, вот леска того, что вы могли бы рассмотреть:
public static void SqlInject(string commandName, params[] object commandArgs)
{
//--> no point in going on if we got no command...
if (string.IsNullOrEmpty(commandName))
throw new ArgumentNullException(nameof(commandName));
var connectionString =
System
.Configuration
.ConfigurationManager
.ConnectionStrings["conProject"]
.ConnectionString;
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "select commandText from dbo.StatementRepository where commandName = @commandName";
command.Parameters.AddWithValue("@commandName", commandName);
var results = command.ExecuteScalar();
if (results != null && results != DbNull.Value)
{
//--> calling a separate method to validate args, that returns
//--> an IDictionary<string,object> of parameter names
//--> and possibly modified arguments.
//--> Let this validation method throw exceptions.
var validatedArgs = ValidateArgs(commandName, commandArgs);
command.Parameters.Clear();
command.CommandText = query;
foreach(var kvp in validatedArgs)
{
command.Parameters.AddWithValue(kvp.Key, kvp.Value);
}
command.ExecuteNonQuery();
}
else
{
throw new InvalidOperationException("Invalid command");
}
}
}
}
Я не пытался написать фактический аргумент метода проверяющий, потому что это все завернутые в вашей логики приложения ... но Я хотел дать вам представление о том, как вы можете добраться до состояния безопаснее.
Можете ли вы предоставить код, чтобы все получили лучшее понимание. – Izzy
см. Обновление – oldman
Да. Не пытайтесь использовать/повторно использовать объекты SqlConnection * * (и любые другие классы, подобные этому). Вы можете поместить соединение * string * в поле 'static', но создайте свои' SqlConnection' и 'SqlCommand' * внутри *' SqlInject' и поместите их создание внутри 'using' операторов. –