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

на главную - закладки

Жанры

Шрифт:

Что дает такая схема, и зачем нужна дополнительная прослойка между 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 {

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

Музыкальный приворот. Часть 2

Анна Джейн
Любовные романы:
современные любовные романы
5.62
рейтинг книги
Музыкальный приворот. Часть 2

Том 4. Белая гвардия, Дни Турбиных (с иллюстрациями)

Булгаков Михаил Афанасьевич
Проза:
классическая проза
5.00
рейтинг книги
Том 4. Белая гвардия, Дни Турбиных (с иллюстрациями)

В осаде

Кетлинская Вера Казимировна
Проза:
военная проза
советская классическая проза
5.00
рейтинг книги
В осаде

StarCraft: сборник рассказов

Нильсон Микки
StarCraft
Фантастика:
боевая фантастика
5.00
рейтинг книги
StarCraft: сборник рассказов

Игры сердца

Эшли Кристен
4. Бург
Любовные романы:
современные любовные романы
эро литература
5.40
рейтинг книги
Игры сердца

И тогда он зачистил город

Тамоников Александр
Детективы:
боевики
7.22
рейтинг книги
И тогда он зачистил город

Всадник на белом коне. Трилогия

Морозевич Юрий В.
Всадник на белом коне
Фантастика:
научная фантастика
космическая фантастика
5.00
рейтинг книги
Всадник на белом коне. Трилогия

Играть... в тебя

Зайцева Мария
3. Звериные повадки Симоновых
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Играть... в тебя

Орк [компиляция]

Марченко Ростислав Александрович
Фантастика:
фэнтези
попаданцы
6.25
рейтинг книги
Орк  [компиляция]

Архил...? 4

Кожевников Павел
4. Архил...?
Фантастика:
фэнтези
попаданцы
альтернативная история
5.50
рейтинг книги
Архил...? 4

Наша навсегда

Зайцева Мария
2. Наша
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Наша навсегда

Стеллар. Компиляция. Книги 1-9

Прокофьев Роман Юрьевич
Стеллар
Фантастика:
киберпанк
рпг
постапокалипсис
технофэнтези
5.00
рейтинг книги
Стеллар. Компиляция. Книги 1-9

Проект «Юпитер»

Холдеман Джо
Фантастика:
боевая фантастика
7.40
рейтинг книги
Проект «Юпитер»

Бронзовый мальчик

Крапивин Владислав Петрович
2. Паруса Эспады
Детские:
детские приключения
8.62
рейтинг книги
Бронзовый мальчик