Чтение онлайн

на главную

Жанры

Шрифт:

Что дает такая схема, и зачем нужна дополнительная прослойка между ORM и бизнес-логикой приложения:

? внедрение хранилища для типовых запросов, например, получения записи по идентификатору или получения всех заявок заказчика, позволит, с одной стороны, унифицировать получение таких данных, а с другой, сделает связь с ORM менее жесткой;

? внедрение сервисов похоже на внедрение хранилищ, только реализующих логику управления данными. Например, хорошей практикой является определение сервиса, который добавляет, изменяет либо удаляет данные. Обращаясь к такому сервису, ваш код

не будет зависеть от реализации функций, существующей ORM и даже базы данных;

? внедрение такого рода инъекций кода отделяет бизнес-логику от ORM и уменьшает зависимость между ними, что позволит в дальнейшем без особых трудов использовать другой ORM, переписав для этого только хранилище и сервисы. В случае же прямой связи бизнес-логики с ORM, безболезненной замены ORM провести не удастся, т. к. придется инспектировать и переписывать весь написанный код.

Возможность замены источника данных

Для более наглядного примера потребности в промежуточном коде и необходимости предусматривать возможные изменения в работе с ORM приведем случай из практики одного из авторов книги. Компания, в которой он работал, разрабатывала крупный проект, работающий с использованием SQL Server 2000. После нескольких лет разработки и поддержки, заказчик пожелал сменить SQL Server на другую СУБД. В связи с тем, что код проекта был жестко завязан на особенностях SQL Server, такой переход стоил больших усилий всего персонала компании.

В то время еще не существовало LINQ для SQL, но даже если бы компания использовала этот ORM, ей все равно пришлось бы переписывать подавляющую часть кода работы с данными в связи с тем, что LINQ для SQL не поддерживает ничего, кроме SQL Server.

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

Реализация слоя данных

Создадим простейший слой для работы с базой данных, который отвечал бы всем нашим требованиям. Для начала возьмем простую структуру базы данных (рис. 3.5).

Рис. 3.5. Структура базы данных

У нас есть три таблицы: заказчики, заказы и товары. Каждая из таблиц содержит набор свойственных ей полей, так в таблице Products (товары) есть поле isAvailible, которое показывает, доступен ли товар в настоящее время. У таблицы Orders (заказы) есть поля count — количество товара в штуках и orderDateTime — дата и время оформления заказа. Таблица Customers (заказчики) содержит информацию о заказчике.

Для реализации хранилищ и сервисов нам необходимы интерфейсы данных, определим их так, как показано в листинге 3.1.

Листинг 3.1. Интерфейсы данных

public interface ICustomer {

Guid CustomerId { set; get; }

string Name { set; get; }

string Phone { set; get; }

string Address { set; get; }

}

public interface IOrder {

Guid OrderId { set; get; }

Guid CustomerId { set; get; }

Guid ProductId { set; get; }

int Count { set; get; }

DateTime OrderDateTime { set; get; }

}

public interface IProduct {

Guid ProductId { set; get; }

string Name { set; get; }

bool IsAvailible { set; get; }

bool Cost { set; get; }

}

Воспользуемся

мастером создания модели LINQ для SQL, чтобы сгенерировать классы для работы с базой данных. Посмотрим на сгенерированный код для таблицы Customers (приведен только фрагмент кода):

public partial class Customer : INotifyPropertyChanging,

INotifyPropertyChanged

{

private System.Guid _customerId;

private string _name;

private string _address;

private string _phone;

private EntitySet<Order> _Orders;

public Customer

{

// код

}

[Column(Storage="_customerId",

DbType="UniqueIdentifier NOT NULL",

IsPrimaryKey=true)] public System.Guid customerId {

get { return this._customerId; }

set { // код }

}

[Column(Storage="_name",

DbType="NVarChar(250) NOT NULL", CanBeNull=false)]

public string name {

get { return this._name; }

set { // код }

}

[Column(Storage="_address",

DbType="NVarChar(1024) NOT NULL",

CanBeNull=false)]

public string address {

get { return this._address; }

set { // код }

}

[Column(Storage="_phone", DbType="NVarChar(250)")]

public string phone {

get { return this._phone; }

set { // код }

}

[Association(Name="Customer_Order",

Storage="_Orders", ThisKey="customerId",

OtherKey="customerId")]

public EntitySet<Order> Orders {

get { return this._Orders; }

set { this._Orders.Assign(value); }

}

}

Полученный код примечателен тем, что класс Customer является partial-классом, а это значит, что мы можем легко расширить его, и все прочие классы, для поддержки наших интерфейсов. Создадим частичные классы для реализации интерфейсов на базе LINQ для SQL так, как показано в листинге 3.2.

Листинг 3.2. Частичные классы с реализацией интерфейсов

public partial class Customer : ICustomer {

public Guid CustomerId {

get { return customerId; }

set { customerId = value; }

}

public string Name {

get { return name; }

set { name = value; }

}

public string Phone {

get { return phone; }

set { phone = value; }

}

public string Address {

Поделиться:
Популярные книги

Третий Генерал: Тома I-II

Зот Бакалавр
1. Третий Генерал
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Третий Генерал: Тома I-II

Методы статистического анализа исторических текстов (часть 2)

Фоменко Анатолий Тимофеевич
Научно-образовательная:
история
5.00
рейтинг книги
Методы статистического анализа исторических текстов (часть 2)

Монстр из прошлого тысячелетия

Еслер Андрей
5. Соприкосновение миров
Фантастика:
попаданцы
аниме
фэнтези
4.75
рейтинг книги
Монстр из прошлого тысячелетия

Эволюционер из трущоб. Том 13

Панарин Антон
13. Эволюционер из трущоб
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Эволюционер из трущоб. Том 13

Диверсанты Сталина: НКВД в тылу врага

Попов Алексей Юрьевич
Силы особого назначения
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Диверсанты Сталина: НКВД в тылу врага

Бриллианты Юстэсов

Троллоп Энтони
3. Романы о Плантагенете Паллисьере
Проза:
современная проза
5.00
рейтинг книги
Бриллианты Юстэсов

Последний реанорец. Том IX

Павлов Вел
8. Высшая Речь
Фантастика:
фэнтези
попаданцы
аниме
5.80
рейтинг книги
Последний реанорец. Том IX

В лапах зверя

Зайцева Мария
1. Звериные повадки Симоновых
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
В лапах зверя

Перстень с трезубцем

Теущаков Александр Александрович
Проза:
историческая проза
6.25
рейтинг книги
Перстень с трезубцем

Стоялов Максим Викторович

Стоялов Максим Викторович
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Стоялов Максим Викторович

Основы общей психологии

Рубинштейн Сергей Леонидович
Мастера психологии
Научно-образовательная:
психология
5.00
рейтинг книги
Основы общей психологии

Вечный Герой (сборник)

Муркок Майкл Джон
Шедевры фантастики
Фантастика:
эпическая фантастика
6.25
рейтинг книги
Вечный Герой (сборник)

Кузнецкий мост (1-3 части)

Дангулов Савва Артемьевич
Проза:
военная проза
6.80
рейтинг книги
Кузнецкий мост (1-3 части)

Виллет

Бронте Шарлотта
Проза:
классическая проза
8.57
рейтинг книги
Виллет