ЖАНРЫ

Шрифт:

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

Создадим простейший слой для работы с базой данных, который отвечал бы всем нашим требованиям. Для начала возьмем простую структуру базы данных (рис. 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 {

get { return address; }

set { address = value; }

}

}

public partial class Order : IOrder {

public Guid OrderId {

get { return orderId; }

set { orderld = value; }

}

public Guid Customerld {

get { return customerId; }

set { customerId = value; }

}

public Guid ProductId {

get { return productId; }

set { productId = value; }

}

public int Count {

get { return count; }

set { count = value; }

}

public DateTime OrderDateTime {

get { return orderDateTime; }

set { orderDateTime = value; }

}

}

public partial class Product : IProduct {

public Guid ProductId {

get { return productId; }

set { productId = value; }

}

public string Name {

get { return name; }

set { name = value; }

}

public bool IsAvailable {

get { return isAvailable; }

set { isAvailable = value; }

}

public decimal Cost {

get { return cost; }

set { cost = value; }

}

}

На этом этапе существует еще одна полезная возможность, которую предлагает инъекция дополнительного кода: вы можете назначать имена для свойств интерфейса, не привязываясь к именам, которые определены в базе данных. Скажем, для поля cost таблицы Products мы могли бы задать другое название, например, ProductCost.

После реализации интерфейсов создадим простейшие хранилища и сервисы, для этого сначала объявим их интерфейсы:

public interface ICustomerRepository {

ICustomer GetCustomerById(Guid customerId);

IEnumerable<ICustomer> GetCustomersByProduct(Guid productId);

}

Хранилище для заказчиков позволит выбирать заказчика по идентификатору и выбирать всех заказчиков, связанных с определенным товаром.

public interface IOrderRepository {

Поделиться с друзьями: