Язык программирования C#9 и платформа .NET5
Шрифт:
=> _connectionString = connectionString;
}
}
Открытие и закрытие подключения
Добавьте переменную уровня класса, которая будет хранить подключение, применяемое кодом доступа к данным. Добавьте также два метода: один для открытия подключения
(OpenConnection
) и еще один для закрытия подключения (CloseConnection
). В методе CloseConnection
проверьте состояние подключения и если оно не закрыто, тогда вызовите метод Close
на объекте подключения. Вот как выглядит
private SqlConnection _sqlConnection = null;
private void OpenConnection
{
_sqlConnection = new SqlConnection
{
ConnectionString = _connectionString
};
_sqlConnection.Open;
}
private void CloseConnection
{
if (_sqlConnection?.State != ConnectionState.Closed)
{
_sqlConnection?.Close;
}
}
Ради краткости в большинстве методов класса
InventoryDal
не будут применяться блоки try/catch
для обработки возможных исключений, равно как не будут генерироваться специальные исключения для сообщения о разнообразных проблемах при выполнении (скажем, неправильно сформированная строка подключения). Если бы строилась библиотека доступа к данным производственного уровня, то определенно пришлось бы использовать приемы структурированной обработки исключений (как объяснялось в главе 7), чтобы учесть любые аномалии времени выполнения. Добавление реализации IDisposable
Добавьте к определению класса интерфейс
IDisposable
:
public class InventoryDal : IDisposable
{
...
}
Затем реализуйте шаблон освобождения, вызывая
Dispose
на объекте SqlConnection
:
bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
_sqlConnection.Dispose;
}
_disposed = true;
}
public void Dispose
{
Dispose(true);
GC.SuppressFinalize(this);
}
Добавление методов выборки
Для начала объедините имеющиеся сведения об объектах команд, чтения данных и обобщенных коллекциях, чтобы получить записи из таблицы
Inventory
. Как было показано в начале главы, объект чтения данных в поставщике делает возможной выборку записей с использованием механизма, который реализует только чтение в прямом направлении с помощью метода Read
.
В этом примере свойство CommandBehavior
класса DataReader
настроено на автоматическое закрытие подключения, когда закрывается объект чтения данных. Метод GetAllInventory
возвращает экземпляр List<CarViewModel>
, представляющий все данные в таблице Inventory
:
public List<CarViewModel> GetAllInventory
{
OpenConnection;
// Здесь будут храниться записи.
List<CarViewModel> inventory = new List<CarViewModel>;
// Подготовить объект команды.
string sql =
@"SELECT i.Id, i.Color, i.PetName,m.Name as Make
FROM Inventory i
INNER JOIN Makes m on m.Id = i.MakeId";
using SqlCommand command =
new SqlCommand(sql, _sqlConnection)
{
CommandType = CommandType.Text
};
command.CommandType = CommandType.Text;
SqlDataReader dataReader =
command.ExecuteReader(CommandBehavior.CloseConnection);
while (dataReader.Read)
{
inventory.Add(new CarViewModel
{
Id = (int)dataReader["Id"],
Color = (string)dataReader["Color"],
Make = (string)dataReader["Make"],
PetName = (string)dataReader["PetName"]
});
}
dataReader.Close;
return inventory;
}
Следующий метод выборки получает одиночный объект
CarViewModel
на основе значения CarId
:
public CarViewModel GetCar(int id)
{
OpenConnection;
CarViewModel car = null;
// Параметры должны применяться по причинам, связанным с безопасностью.
string sql =
$@"SELECT i.Id, i.Color, i.PetName,m.Name as Make
FROM Inventory i
INNER JOIN Makes m on m.Id = i.MakeId
WHERE i.Id = {id}";
using SqlCommand command =
new SqlCommand(sql, _sqlConnection)
{
CommandType = CommandType.Text
};
SqlDataReader dataReader =
command.ExecuteReader(CommandBehavior.CloseConnection);
while (dataReader.Read)
{
car = new CarViewModel
{
Id = (int) dataReader["Id"],
Поделиться с друзьями: