Asp.net mvc framework
Шрифт:
Реализация слоя данных
Создадим простейший слой для работы с базой данных, который отвечал бы всем нашим требованиям. Для начала возьмем простую структуру базы данных (рис. 3.5).
Рис. 3.5. Структура базы данных
У нас есть три таблицы: заказчики, заказы и товары. Каждая из таблиц содержит набор свойственных ей полей, так в таблице Products (товары)
Для реализации хранилищ и сервисов нам необходимы интерфейсы данных, определим их так, как показано в листинге 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 {