Для .Net есть много ORM: Entity Framework, Linq2SQL, NHibernate, Data Access, BLToolkit и много-много других известных и не очень. У каждой из них есть как плюсы так и свои недостатки. В нескольких следующих статьях я попробую сравнить удобство использования некоторых ORM в стандартных ситуациях. Сравнивать будем следующим способом: сделаем небольшой сайтик на ASP.Net MVC и организуем его связь с базой данных с помощью разных ORM и посмотрим, с какими особенностями и проблемами столкнёмся в ходе выполнения задачи.
Темой сайта будет: сервисный центр по ремонту техники, база данных - MS SQL Server 2008, структура таблиц следующая:
Первой целью изучения будет 'Business Logic Toolkit for .NET' или просто BLToolkit. Получить его можно по ссылке или через nuget
Install-Package BLToolkit
Создадим ASP.Net MVC проект ServiceCenter и DLL-проект ServiceCenter.Data.BLT для работы с базой данных. В Web.config проекта ServiceCenter в раздел ConnectionStrings добавим строку подключения к БД
<add name="ServiceCenter"connectionString="Server=localhost\mssql2k8r2;Database=ServiceCenter;Integrated Security=SSPI"providerName="System.Data.SqlClient"/>
Далее работаем с проектом ServiceCenter.Data.BLT.
Создаём классы DeviceType, Position, Status, Manufacturer, Employee, Request
using System; using System.Collections.Generic; using System.ComponentModel; using DataAnnotations = System.ComponentModel.DataAnnotations; using BLToolkit.Common; using BLToolkit.DataAccess; using BLToolkit.Mapping;
///<summary> /// Тип устройства ///</summary> [TableName("DeviceType")] public class DeviceType : EntityBase { ///<summary> /// Пустой конструктор для BLToolkit ///</summary> public DeviceType() { } public DeviceType(DeviceType deviceType) { this.Id = deviceType.Id; this.Value = deviceType.Value; } [MapField("DeviceTypeId"), PrimaryKey, Identity, NonUpdatable, DisplayName("Id")] public int Id { get; set; } ///<summary> /// Наименование ///</summary> [NotNull, DisplayName("Наименование"), DataAnnotations.Required(ErrorMessage = "Наименование не может быть пустым"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string Value { get; set; } ///<summary> /// Заявки ///</summary> [Association(CanBeNull = true, ThisKey = "Id", OtherKey = "DeviceTypeId"), DisplayName("Заявки")] public List<Request> Requests { get; set; } }
///<summary> /// Должность ///</summary> [TableName("Position")] public class Position : EntityBase { ///<summary> /// Пустой конструктор для BLToolkit ///</summary> public Position() { } public Position(Position position) { this.Id = position.Id; this.Value = position.Value; } [MapField("PositionId"), PrimaryKey, Identity, NonUpdatable, DisplayName("Id")] public int Id { get; set; } ///<summary> /// Наименование ///</summary> [NotNull, DisplayName("Наименование"), DataAnnotations.Required(ErrorMessage = "Наименование не может быть пустым"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string Value { get; set; } ///<summary> /// Сотрудники ///</summary> [Association(CanBeNull = true, ThisKey = "Id", OtherKey = "PositionId"), DisplayName("Сотрудники")] public List<Employee> Employees { get; set; } }
///<summary> /// Статус заявки ///</summary> [TableName("Status")] public class Status : EntityBase { ///<summary> /// Пустой конструктор для BLToolkit ///</summary> public Status() { } public Status(Status status) { this.Id = status.Id; this.Value = status.Value; } [MapField("StatusId"), PrimaryKey, Identity, NonUpdatable, DisplayName("Id")] public int Id { get; set; } ///<summary> /// Наименование ///</summary> [NotNull, DisplayName("Наименование"), DataAnnotations.Required(ErrorMessage = "Наименование не может быть пустым"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string Value { get; set; } ///<summary> /// Заявки ///</summary> [Association(CanBeNull = true, ThisKey = "Id", OtherKey = "StatusId"), DisplayName("Заявки")] public List<Request> Requests { get; set; } }
///<summary> /// Производитель ///</summary> [TableName("Manufacturer"), DisplayName("Производитель")] public class Manufacturer : EntityBase { ///<summary> /// Пустой конструктор для BLToolkit ///</summary> public Manufacturer() { } public Manufacturer(Manufacturer manufacturer) { this.Id = manufacturer.Id; this.Value = manufacturer.Value; } [MapField("ManufacturerId"), PrimaryKey, Identity, NonUpdatable, DisplayName("Id")] public int Id { get; set; } ///<summary> /// Наименование ///</summary> [NotNull, DisplayName("Наименование"), DataAnnotations.Required(ErrorMessage = "Наименование не может быть пустым"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string Value { get; set; } ///<summary> /// Заявки ///</summary> [Association(CanBeNull = true, ThisKey = "Id", OtherKey = "ManufacturerId"), DisplayName("Заявки")] public List<Request> Requests { get; set; } }
///<summary> /// Сотрудник ///</summary> [TableName("Employee")] public class Employee : EntityBase { ///<summary> /// Пустой конструктор для BLToolkit ///</summary> public Employee() { } public Employee(Employee employee) { this.Id = employee.Id; this.SurName = employee.SurName; this.Name = employee.Name; this.MidName = employee.MidName; this.PositionId = employee.PositionId; this.Position = employee.Position; } [MapField("EmployeeId"), PrimaryKey, Identity, NonUpdatable, DisplayName("Id")] public int Id { get; set; } ///<summary> /// Имя ///</summary> [NotNull, DisplayName("Имя"), DataAnnotations.Required(ErrorMessage = "Имя не может быть пустым"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string Name { get; set; } ///<summary> /// Фамилия ///</summary> [Nullable, DisplayName("Фамилия"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string SurName { get; set; } ///<summary> /// Отчество ///</summary> [Nullable, DisplayName("Отчество"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")] public string MidName { get; set; } ///<summary> /// Должность ///</summary> [MapField("PositionId"), NotNull, DisplayName("Должность")] public int PositionId { get; set; } ///<summary> /// Должность ///</summary> [Association(CanBeNull = false, ThisKey = "PositionId", OtherKey = "Id"), DisplayName("Должность")] public Position Position { get; set; } ///<summary> /// Полное имя ///</summary> [MapIgnore, DisplayName("Ф.И.О.")] public string FullName { get { string fullName = this.Name; if (!string.IsNullOrEmpty(this.SurName) && !string.IsNullOrEmpty(this.MidName)) fullName = string.Format("{0} {1}.{2}.", this.SurName, this.Name[0], this.MidName[0]); else if (!string.IsNullOrEmpty(this.SurName)) fullName = string.Format("{0} {1}", this.SurName, this.Name); return fullName; } } ///<summary> /// Заявки ///</summary> [Association(ThisKey = "Id", OtherKey = "EmployeeId"), DisplayName("Заявки")] public List<Request> Requests { get; set; } }
///<summary>
/// Заявка
///</summary>
[TableName("Request")]
public class Request : EntityBase
{
///<summary>
/// Пустой конструктор для BLToolkit
///</summary>
public Request()
{
}
public Request(Request request)
{
this.Id = request.Id;
this.EmployeeId = request.EmployeeId;
this.DateIn = request.DateIn;
this.DateOut = request.DateOut;
this.DeviceTypeId = request.DeviceTypeId;
this.ManufacturerId = request.ManufacturerId;
this.Model = request.Model;
this.Description = request.Description;
this.ClientName = request.ClientName;
this.ClientPhone = request.ClientPhone;
this.Cost = request.Cost;
this.StatusId = request.StatusId;
this.Comment = request.Comment;
}
[MapField("RequestId"), PrimaryKey, Identity, NonUpdatable, DisplayName("Id")]
public int Id { get; set; }
///<summary>
/// Ответственный/исполнитель
///</summary>
[MapField("EmployeeId"), NotNull, DisplayName("Ответственный/исполнитель")]
public int EmployeeId { get; set; }
///<summary>
/// Ответственный/исполнитель
///</summary>
[Association(CanBeNull = false, ThisKey = "EmployeeId", OtherKey = "Id"), DisplayName("Ответственный/исполнитель")]
public Employee Employee { get; set; }
///<summary>
/// Статус заявки
///</summary>
[MapField("StatusId"), NotNull, DisplayName("Статус заявки")]
public int StatusId { get; set; }
///<summary>
/// Статус заявки
///</summary>
[Association(CanBeNull = false, ThisKey = "StatusId", OtherKey = "Id"), DisplayName("Статус заявки")]
public Status Status { get; set; }
///<summary>
/// Дата приёма
///</summary>
[NotNull, DisplayName("Дата приёма"), DataAnnotations.DataType(DataAnnotations.DataType.Date)]
public DateTime DateIn { get; set; }
///<summary>
/// Дата выдачи
///</summary>
[NullDateTime, DisplayName("Дата выдачи"), DataAnnotations.DataType(DataAnnotations.DataType.Date)]
public DateTime? DateOut { get; set; }
///<summary>
/// Производитель
///</summary>
[MapField("ManufacturerId"), NotNull, DisplayName("Производитель")]
public int ManufacturerId { get; set; }
///<summary>
/// Производитель
///</summary>
[Association(CanBeNull = false, ThisKey = "ManufacturerId", OtherKey = "Id"), DisplayName("Производитель")]
public Manufacturer Manufacturer { get; set; }
///<summary>
/// Тип устройства
///</summary>
[MapField("DeviceTypeId"), NotNull, DisplayName("Тип устройства")]
public int DeviceTypeId { get; set; }
///<summary>
/// Тип устройства
///</summary>
[Association(CanBeNull = false, ThisKey = "DeviceTypeId", OtherKey = "Id"), DisplayName("Тип устройства")]
public DeviceType DeviceType { get; set; }
///<summary>
/// Модель
///</summary>
[NotNull, DisplayName("Модель")]
public string Model { get; set; }
///<summary>
/// Описание неисправности
///</summary>
[NotNull, DisplayName("Описание неисправности"), DataAnnotations.DataType(DataAnnotations.DataType.MultilineText), DataAnnotations.StringLength(250, ErrorMessage = "Максимум 250 символов")]
public string Description { get; set; }
///<summary>
/// Ф.И.О. клиента
///</summary>
[NotNull, DisplayName("Ф.И.О. клиента"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(150, ErrorMessage = "Максимум 150 символов")]
public string ClientName { get; set; }
///<summary>
/// Телефон клиента
///</summary>
[Nullable, DisplayName("Телефон клиента"), DataAnnotations.DataType(DataAnnotations.DataType.Text), DataAnnotations.StringLength(50, ErrorMessage = "Максимум 50 символов")]
public string ClientPhone { get; set; }
///<summary>
/// Стоимость ремонта
///</summary>
[NotNull, DisplayName("Стоимость ремонта"), DataAnnotations.Range(0, 10000, ErrorMessage = "Введите значение от 0 до 10000")]
public int Cost { get; set; }
///<summary>
/// Комметарий исполнителя
///</summary>
[Nullable, DisplayName("Комметарий исполнителя"), DataAnnotations.DataType(DataAnnotations.DataType.MultilineText), DataAnnotations.StringLength(250, ErrorMessage = "Максимум 250 символов")]
public string Comment { get; set; }
}
С помощью атрибута MapField мы указываем к каким полем в БД следует связать свойство класса, MapIgnore - свойство класса не связано с полем в БД, Association - связывает между собой два класса (работает только связь один-к-одному).
Создаём DbManager, который будет предоставлять нам доступ к содержимому таблиц
namespace ServiceCenter.Data.BLT
{
using System;
using BLToolkit.Data;
using BLToolkit.Data.Linq;
public class ServiceCenterDB : DbManager
{
public Table<DeviceType> DeviceTypes { get { return GetTable<DeviceType>(); } }
public Table<Employee> Employees { get { return GetTable<Employee>(); } }
public Table<Manufacturer> Manufacturers { get { return GetTable<Manufacturer>(); } }
public Table<Position> Positions { get { return GetTable<Position>(); } }
public Table<Request> Requests { get { return GetTable<Request>(); } }
public Table<Status> Statuses { get { return GetTable<Status>(); } }
}
}
Создаём класс, который будет возвращать нам необходимые данные
#region Using
using System;
using System.Collections.Generic;
using System.Linq;
using BLToolkit.Data;
using BLToolkit.Data.Linq;
using BLToolkit.Linq;
#endregion
public class DataService
{
#region Конструктор
public DataService()
{
BLToolkit.Common.Configuration.Linq.AllowMultipleQuery = true;
}
#endregion
#region Производитель
///<summary>
/// Возвращает список всех производителей
///</summary>
public List<Manufacturer> GetManufacturers()
{
List<Manufacturer> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = db.Manufacturers.ToList();
}
return result;
}
///<summary>
/// Возвращает производителя
///</summary>
public Manufacturer GetManufacturer(int id)
{
Manufacturer result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.Manufacturers
where x.Id == id
select new Manufacturer(x)
{
Requests = (from y in db.Requests
where y.Manufacturer == x
select new Request(y)
{
Employee = y.Employee,
DeviceType = y.DeviceType,
Manufacturer = x,
Status = y.Status
}).ToList()
}).FirstOrDefault();
}
return result;
}
///<summary>
/// Сохранить производителя
///</summary>
public void SaveManufacturer(Manufacturer manufacturer)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (manufacturer.Id == 0)
db.Into(db.Manufacturers).Value(x => x.Value, manufacturer.Value).Insert();
else
db.Manufacturers.Where(x => x.Id == manufacturer.Id).Set(x => x.Value, manufacturer.Value).Update();
}
}
///<summary>
/// Удалить производителя
///</summary>
public void DeleteManufacturer(Manufacturer manufacturer)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.Manufacturers.Where(x => x.Id == manufacturer.Id).Delete();
}
}
#endregion
#region Состояние заявки
///<summary>
/// Возвращает список всех состояний заявок
///</summary>
public List<Status> GetStatuses()
{
List<Status> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = db.Statuses.ToList();
}
return result;
}
///<summary>
/// Возвращает состояние заявки
///</summary>
public Status GetStatus(int id)
{
Status result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.Statuses
where x.Id == id
select new Status(x)
{
Requests = (from y in db.Requests
where y.Status == x
select new Request(y)
{
Employee = y.Employee,
DeviceType = y.DeviceType,
Manufacturer = y.Manufacturer,
Status = x
}).ToList()
}).FirstOrDefault();
}
return result;
}
///<summary>
/// Сохранить состояние заявки
///</summary>
public void SaveStatus(Status status)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (status.Id == 0)
db.Into(db.Statuses).Value(x => x.Value, status.Value).Insert();
else
db.Statuses.Where(x => x.Id == status.Id).Set(x => x.Value, status.Value).Update();
}
}
///<summary>
/// Удалить состояние заявки
///</summary>
public void DeleteStatus(Status status)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.Statuses.Where(x => x.Id == status.Id).Delete();
}
}
#endregion
#region Тип устройства
///<summary>
/// Возвращает список всех типов устройств
///</summary>
public List<DeviceType> GetDeviceTypes()
{
List<DeviceType> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = db.DeviceTypes.ToList();
}
return result;
}
///<summary>
/// Возвращает тип устройства
///</summary>
public DeviceType GetDeviceType(int id)
{
DeviceType result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.DeviceTypes
where x.Id == id
select new DeviceType(x)
{
Requests = (from y in db.Requests
where y.DeviceType == x
select new Request(y)
{
Employee = y.Employee,
DeviceType = x,
Manufacturer = y.Manufacturer,
Status = y.Status
}).ToList()
}).FirstOrDefault();
}
return result;
}
///<summary>
/// Сохранить тип устройства
///</summary>
public void SaveDeviceType(DeviceType deviceType)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (deviceType.Id == 0)
db.Into(db.DeviceTypes).Value(x => x.Value, deviceType.Value).Insert();
else
db.DeviceTypes.Where(x => x.Id == deviceType.Id).Set(x => x.Value, deviceType.Value).Update();
}
}
///<summary>
/// Удалить тип устройства
///</summary>
public void DeleteDeviceType(DeviceType deviceType)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.DeviceTypes.Where(x => x.Id == deviceType.Id).Delete();
}
}
#endregion
#region Должности
///<summary>
/// Возвращает список всех должностей
///</summary>
public List<Position> GetPositions()
{
List<Position> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = db.Positions.ToList();
}
return result;
}
///<summary>
/// Возвращает должность
///</summary>
public Position GetPosition(int id)
{
Position result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.Positions
where x.Id == id
select new Position(x)
{
Employees = (from y in db.Employees
where y.Position == x
select new Employee(y)
{
Position = x
}).ToList()
}).FirstOrDefault();
}
return result;
}
///<summary>
/// Сохранить должность
///</summary>
public void SavePosition(Position position)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (position.Id == 0)
db.Into(db.Positions).Value(x => x.Value, position.Value).Insert();
else
db.Positions.Where(x => x.Id == position.Id).Set(x => x.Value, position.Value).Update();
}
}
///<summary>
/// Удалить должность
///</summary>
public void DeletePosition(Position position)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.Positions.Where(x => x.Id == position.Id).Delete();
}
}
#endregion
#region Сотрудники
///<summary>
/// Возвращает список всех сотрудников
///</summary>
public List<Employee> GetEmployees()
{
List<Employee> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
var query = from x in db.Employees
orderby x.SurName, x.Name
select new Employee(x)
{
Position = x.Position
};
result = query.ToList();
}
return result;
}
///<summary>
/// Возвращает сотрудника
///</summary>
public Employee GetEmployee(int id)
{
Employee result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.Employees
where x.Id == id
select new Employee(x)
{
Position = x.Position,
Requests = (from y in db.Requests
where y.Employee == x
select new Request(y)
{
Employee = x,
DeviceType = y.DeviceType,
Manufacturer = y.Manufacturer,
Status = y.Status
}).ToList()
}).FirstOrDefault();
}
return result;
}
///<summary>
/// Сохранить сотрудника
///</summary>
public void SaveEmployee(Employee employee)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (employee.Id == 0)
db.Into(db.Employees)
.Value(x => x.SurName, employee.SurName)
.Value(x => x.Name, employee.Name)
.Value(x => x.MidName, employee.MidName)
.Value(x => x.PositionId, employee.PositionId).Insert();
else
db.Employees.Where(x => x.Id == employee.Id)
.Set(x => x.SurName, employee.SurName)
.Set(x => x.Name, employee.Name)
.Set(x => x.MidName, employee.MidName)
.Set(x => x.PositionId, employee.PositionId).Update();
}
}
///<summary>
/// Удалить сотрудника
///</summary>
public void DeleteEmployee(Employee employee)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.Employees.Where(x => x.Id == employee.Id).Delete();
}
}
#endregion
#region Заявки
///<summary>
/// Возвращает список всех заявок
///</summary>
public List<Request> GetRequests()
{
List<Request> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
var query = from x in db.Requests
orderby x.DateIn
select new Request(x)
{
Employee = x.Employee,
DeviceType = x.DeviceType,
Manufacturer = x.Manufacturer,
Status = x.Status
};
result = query.ToList();
}
return result;
}
///<summary>
/// Возвращает заявку
///</summary>
public Request GetRequest(int id)
{
Request result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.Requests
where x.Id == id
select new Request(x)
{
Employee = x.Employee,
DeviceType = x.DeviceType,
Manufacturer = x.Manufacturer,
Status = x.Status
}).FirstOrDefault();
}
return result;
}
///<summary>
/// Сохранить заявку
///</summary>
public void SaveRequest(Request request)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (request.Id == 0)
db.Into(db.Requests)
.Value(x => x.EmployeeId, request.EmployeeId)
.Value(x => x.DateIn, Sql.CurrentTimestamp2)
.Value(x => x.DeviceTypeId, request.DeviceTypeId)
.Value(x => x.ManufacturerId, request.ManufacturerId)
.Value(x => x.Model, request.Model)
.Value(x => x.Description, request.Description)
.Value(x => x.ClientName, request.ClientName)
.Value(x => x.ClientPhone, request.ClientPhone)
.Value(x => x.Cost, request.Cost)
.Value(x => x.StatusId, request.StatusId).Insert();
else
db.Requests.Where(x => x.Id == request.Id)
.Set(x => x.EmployeeId, request.EmployeeId)
.Set(x => x.DateOut, request.StatusId == 5 || request.StatusId == 6 ? Sql.CurrentTimestamp2 : (DateTime?)null)
.Set(x => x.DeviceTypeId, request.DeviceTypeId)
.Set(x => x.ManufacturerId, request.ManufacturerId)
.Set(x => x.Model, request.Model)
.Set(x => x.Description, request.Description)
.Set(x => x.ClientName, request.ClientName)
.Set(x => x.ClientPhone, request.ClientPhone)
.Set(x => x.Cost, request.Cost)
.Set(x => x.StatusId, request.StatusId)
.Set(x => x.Comment, request.Comment).Update();
}
}
///<summary>
/// Удалить заявку
///</summary>
public void DeleteRequest(Request request)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.Requests.Where(x => x.Id == request.Id).Delete();
}
}
#endregion
}
Рассмотрим подробнее методы работы с сотрудниками: GetEmployees(), GetEmployee(int id), SaveEmployee(Employee employee) и DeleteEmployee(Employee employee)
GetEmployees() - при наличии свойства PositionId, на которое ссылается ассоциация Position, BLToolkit автоматически заполняет свойство класса PositionId, но не заполняет ассоциацию Position, выход - использовать конструктор копирования и заполнить ассоциацию вручную. Непривычно, но как есть
public List<Employee> GetEmployees()
{
List<Employee> result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
var query = from x in db.Employees
orderby x.SurName, x.Name
select new Employee(x)
{
Position = x.Position
};
result = query.ToList();
}
return result;
}
GetEmployee(int id) - то же самое что и для GetEmployees() - заполняем ассоциации вручную, только идём немного глубже и подгружаем также список заявок и их свойств
public Employee GetEmployee(int id)
{
Employee result = null;
using (ServiceCenterDB db = new ServiceCenterDB())
{
result = (from x in db.Employees
where x.Id == id
select new Employee(x)
{
Position = x.Position,
Requests = (from y in db.Requests
where y.Employee == x
select new Request(y)
{
Employee = x,
DeviceType = y.DeviceType,
Manufacturer = y.Manufacturer,
Status = y.Status
}).ToList()
}).FirstOrDefault();
}
return result;
}
SaveEmployee(Employee employee) - сохранение/обновление записи происходит следующим образом
public void SaveEmployee(Employee employee)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
if (employee.Id == 0)
db.Into(db.Employees)
.Value(x => x.SurName, employee.SurName)
.Value(x => x.Name, employee.Name)
.Value(x => x.MidName, employee.MidName)
.Value(x => x.PositionId, employee.PositionId).Insert();
else
db.Employees.Where(x => x.Id == employee.Id)
.Set(x => x.SurName, employee.SurName)
.Set(x => x.Name, employee.Name)
.Set(x => x.MidName, employee.MidName)
.Set(x => x.PositionId, employee.PositionId).Update();
}
}
DeleteEmployee(Employee employee) - удаление записи, ничего особенного тут нет
public void DeleteEmployee(Employee employee)
{
using (ServiceCenterDB db = new ServiceCenterDB())
{
db.Employees.Where(x => x.Id == employee.Id).Delete();
}
}
На этом с проектом ServiceCenter.Data.BLT закончили, посмотрим в основном MVC-проекте пример контроллера работы с заявками. Что контроллер умеет делать: выводит список всех заявок, список заявок по исполнителю, список заявок по статусу, список заявок по производителю, умеет создавать новую заявку, редактировать существующую, а также выбранную зявку. В общем, ничего сложного и требующего пояснений нет
#region Using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Data = ServiceCenter.Data.BLT;
#endregion
public class RequestController : Controller
{
#region Список
public ActionResult Index()
{
ViewBag.Title = "Заявки";
Data.DataService ds = new Data.DataService();
List<Data.Request> requests = ds.GetRequests().OrderBy(x => x.DateIn).ToList();
return View(requests);
}
///<summary>
/// Список заявок сотрудника
///</summary>
///<param name="id">Id сотрудника</param>
public ActionResult Employee(int id)
{
ViewBag.Title = "Заявки";
Data.DataService ds = new Data.DataService();
Data.Employee employee = ds.GetEmployee(id);
ViewBag.Message = string.Format("Для сотрудника: {0}", employee.FullName);
return View(employee.Requests.OrderBy(x => x.DateIn));
}
///<summary>
/// Список заявок со статусом
///</summary>
///<param name="id">Id статуса</param>
public ActionResult Status(int id)
{
ViewBag.Title = "Заявки";
Data.DataService ds = new Data.DataService();
Data.Status status = ds.GetStatus(id);
ViewBag.Message = string.Format("Со статусом: {0}", status.Value);
return View(status.Requests.OrderBy(x => x.DateIn));
}
///<summary>
/// Список заявок по производителю
///</summary>
///<param name="id">Id производителя</param>
public ActionResult Manufacturer(int id)
{
ViewBag.Title = "Заявки";
Data.DataService ds = new Data.DataService();
Data.Manufacturer manufacturer = ds.GetManufacturer(id);
ViewBag.Message = string.Format("Производитель: {0}", manufacturer.Value);
return View(manufacturer.Requests.OrderBy(x => x.DateIn));
}
#endregion
#region Создание
public ActionResult Create()
{
ViewBag.Title = "Заявки - добавление записи";
return View();
}
[HttpPost]
public ActionResult Create(Data.Request request, FormCollection collection)
{
ViewBag.Title = "Заявки - добавление записи";
bool hasErrors = false;
int employeeId = 0;
if (!Int32.TryParse(collection["EmployeeId"], out employeeId))
{
ModelState.AddModelError("", "Выберите исполнителя!");
hasErrors = true;
}
int deviceTypeId = 0;
if (!Int32.TryParse(collection["DeviceTypeId"], out deviceTypeId))
{
ModelState.AddModelError("", "Выберите тип устройства!");
hasErrors = true;
}
int manufacturerId = 0;
if (!Int32.TryParse(collection["ManufacturerId"], out manufacturerId))
{
ModelState.AddModelError("", "Выберите производителя!");
hasErrors = true;
}
if (string.IsNullOrEmpty(request.Model))
{
ModelState.AddModelError("", "Название модели не может быть пустым!");
hasErrors = true;
}
if (string.IsNullOrEmpty(request.Description))
{
ModelState.AddModelError("", "Описание проблемы не может быть пустым!");
hasErrors = true;
}
if (string.IsNullOrEmpty(request.ClientName))
{
ModelState.AddModelError("", "Имя клиента не может быть пустым!");
hasErrors = true;
}
if (hasErrors)
return View();
request.EmployeeId = employeeId;
request.DeviceTypeId = deviceTypeId;
request.ManufacturerId = manufacturerId;
request.StatusId = 1;
Data.DataService ds = new Data.DataService();
try
{
ds.SaveRequest(request);
return RedirectToAction("Index");
}
catch (Exception ex)
{
ModelState.AddModelError("", string.Format("При создании записи возникла ошибка:{0}{1}", Environment.NewLine, ex.Message));
return View();
}
}
#endregion
#region Редактирование
public ActionResult Edit(int id)
{
ViewBag.Title = "Сотрудники - редактирование записи";
Data.DataService ds = new Data.DataService();
Data.Request request = ds.GetRequest(id);
ViewBag.Message = string.Format("Заявка №{0} от {1:dd.MM.yyyy}", request.Id, request.DateIn);
return View(request);
}
[HttpPost]
public ActionResult Edit(Data.Request request, FormCollection collection)
{
ViewBag.Title = "Сотрудники - редактирование записи";
ViewBag.Message = string.Format("Заявка №{0} от {1:dd.MM.yyyy}", request.Id, request.DateIn);
bool hasErrors = false;
int employeeId = 0;
if (!Int32.TryParse(collection["EmployeeId"], out employeeId))
{
ModelState.AddModelError("", "Выберите исполнителя!");
hasErrors = true;
}
int deviceTypeId = 0;
if (!Int32.TryParse(collection["DeviceTypeId"], out deviceTypeId))
{
ModelState.AddModelError("", "Выберите тип устройства!");
hasErrors = true;
}
int manufacturerId = 0;
if (!Int32.TryParse(collection["ManufacturerId"], out manufacturerId))
{
ModelState.AddModelError("", "Выберите производителя!");
hasErrors = true;
}
if (string.IsNullOrEmpty(request.Model))
{
ModelState.AddModelError("", "Название модели не может быть пустым!");
hasErrors = true;
}
if (string.IsNullOrEmpty(request.Description))
{
ModelState.AddModelError("", "Описание проблемы не может быть пустым!");
hasErrors = true;
}
if (string.IsNullOrEmpty(request.ClientName))
{
ModelState.AddModelError("", "Имя клиента не может быть пустым!");
hasErrors = true;
}
int statusId = 0;
if (!Int32.TryParse(collection["StatusId"], out statusId))
{
ModelState.AddModelError("", "Укажите статус заявки!");
hasErrors = true;
}
if (hasErrors)
return View(request);
request.EmployeeId = employeeId;
request.DeviceTypeId = deviceTypeId;
request.ManufacturerId = manufacturerId;
request.StatusId = statusId;
Data.DataService ds = new Data.DataService();
try
{
ds.SaveRequest(request);
return RedirectToAction("Index");
}
catch (Exception ex)
{
ModelState.AddModelError("", string.Format("При редактировании записи возникла ошибка:{0}{1}", Environment.NewLine, ex.Message));
return View(request);
}
}
#endregion
#region Удаление
public ActionResult Delete(int id)
{
Data.DataService ds = new Data.DataService();
Data.Request request = ds.GetRequest(id);
ds.DeleteRequest(request);
return RedirectToAction("Index");
}
#endregion
}
На этом всё, архив с проектом находится во вложении, дамп базы данных там же.
Скриншоты работающего сайта: