[Из песочницы] Уроки по FluentNHibernate c ASP.NET MVC и SQL Server. Часть 1
Что будет? Уроки по FluentNHibernate на примере книжного сайта, где будем возможность просматривать информацию о книге, выводить список книг, фильтровать его по жанрам, осуществлять поиск по названию, а также добавлять, редактировать, удалять книги. Будут рассмотрены все виды связей таблиц (один-к-одному, один-ко-многим, многие-ко-многим), создание, редактирование, удаление записей, фильтрация, поиск, отображение постранично. Программы, используемые в уроках: Visual studio 2013, SQL Server 2008 Manager Studio.
Для быстрого ознакомления с простой операцией CRUD с NHibernate и MVC рекомендую прочитать следующую статью на английском: www.dotnetjalps.com/2014/07/fluent-nhibernate-asp-net-mvc-crud.html.
Также полезные статьи можно найти здесь: github.com/jagregory/fluent-nhibernate/wiki/Getting-started (англ); и его перевод: habrahabr.ru/post/125135.
Еще ссылки на русском языке: slynetblog.blogspot.com/2009/10/nhibernate-1.html
1. ЗАПУСК ПЕРВОГО ПРИЛОЖЕНИЯ
1.1 Установка Fluent NHibernate
Открываем Visual Studio, открываем меню File, переходим на подменю New и Project. В открывшемся окне выбираем ASP.NET MVC 4 (Если выбран .Net Framework 4 Версии). Вводим ему название «BibliotecaTutor» и выбираем тип «Basic». (Далее я буду сокращено писать File→New→Project, а RClick — правая кнопка)
Далее запускаем Nuget Package (Tools→Library Package Manager→Package Manager Console). Прописываем следующую строку: Install-Package FluentNHibernate. Нажимаем Enter, и ждем завершения установки FluentNHibernat’a.
Если нужно установить определенную версию FluentNhibernate, то ищем строку на сайте NuGet www.nuget.org/packages/FluentNHibernate/2.0.1 в таблице Version.
1.2 Настройка FluentNHibernate
- Откроем БД SQL Server Manager и создадим там БД «Biblioteca»
- Откроем Visual Studio, в папке «Models» создадим класс «Book.cs» (Models→Book.cs)
- Создаем в Models папку NHibernate и добавляем туда класс NHibernateHelper.cs (Models→NHibernate→NHibernateHelper.cs)
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
public class NHibernateHelper {
public static ISession OpenSession() {
ISessionFactory sessionFactory = Fluently.Configure()
//Настройки БД. Строка подключения к БД MS Sql Server 2008
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(@"Server=..\SQLENTERPRISE; initial catalog= Biblioteca; Integrated Security=SSPI;")
.ShowSql()
)
//Маппинг. Используя AddFromAssemblyOf NHibernate будет пытаться маппить КАЖДЫЙ класс в этой сборке (assembly). Можно выбрать любой класс.
.Mappings(m =>m.FluentMappings.AddFromAssemblyOf())
//SchemeUpdate позволяет создавать/обновлять в БД таблицы и поля (2 поле ==true)
.ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true))
.BuildSessionFactory();
return sessionFactory.OpenSession();
}
}
1.3 Связи, Классы, Маппинги
В проекте будут созданы следующие таблицы: Book, Author, Genre, Series и Mind.
1.3.1 Связи
Один-к-одному — любому экземпляру сущности А соответствует только один экземпляр сущности В, и наоборот. Пример, таблицы Book и Mind. Если я написал рецензию на книгу «Метро 2033», то я не могу применить точно такую же рецензию на книгу «Метро 2034», а на «Метро 2033» не подойдет моя рецензия на книгу «Метро 2034».
Связь один-к-одному редко применяют, так как все эти данные с успехом можно поместить в одну таблицу. Её применяют в тех случаях, если по каким-то причинам вы хотите одну таблицу разделить на две таблицы. К примеру, те поля, которые оказываются часто пустыми, я помещаю в отдельную таблицу.
«Один-ко-многим»/ «многие-к-одному» — любому экземпляру сущности А соответствует 0, 1 или несколько экземпляров сущности В, но любому экземпляру сущности В соответствует только один экземпляр сущности А. Пример Book и Series. В одной серии/цикле может быть множество книг, но сама книга может входить только в одну серию/цикл.
Какая же разница между связями «один-ко-многим» и «многие-к-одному»? Такая же, как между фразами «портфель ученика» и «ученик портфеля». То есть важно, кто во взаимоотношении двух объектов главный — ученик или портфель.
«Многие-ко-многим» — любому экземпляру сущности А соответствует 0, 1 или несколько экземпляров сущности В, и любому экземпляру сущности В соответствует 0, 1 или несколько экземпляров сущности А. Пример Book и Author, Book и Genre. Над одной книгой, к примеру, антологией, работает несколько авторов, но и у автора могут быть несколько книг. Эти таблицы связаны друг с другом с помощью промежуточных таблиц, таких как Book_Author и Book_Genre.
1.3.2 Класс Book и его Маппинг
Давайте создадим простое приложение, которое будет отображать на веб-странице данные о книге, сохраненной в БД SQL Server. Заполняем класс Book и создаем маппинг класс к нему.
using System;
using FluentNHibernate.Mapping;
namespace BibliotecaTutor.Models {
public class Book {
public virtual int Id { get; set; }
//Название
public virtual string Name { get; set; }
//Описание
public virtual string Description { get; set; }
//Оценка Мира фантастики
public virtual int MfRaiting { get; set; }
////Номера страниц
public virtual int PageNumber { get; set; }
//Ссылка на картинку
public virtual string Image { get; set; }
//Дата поступления книги (фильтр по новикам!)
public virtual DateTime IncomeDate { get; set; }
}
//Маппинг класса
public class BookMap : ClassMap {
public BookMap() {
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Description);
Map(x => x.MfRaiting);
Map(x => x.PageNumber);
Map(x => x.Image);
Map(x => x.IncomeDate);
}
}
}
Для чего нужен Маппинг? С его помощью мы осуществляем связь данных класса Book с таблицей Book (которая будет чуть позже создана), изменяем названия столбцов, определяем виды связей и так далее.
После создания Модели Book следует создать контроллер (Controller→RClick→Add→Controller) и назывем его HomeController. Пишем код, выводящий все книги из таблицы Book.
public ActionResult Index()
{
using (ISession session = NHibernateHelper.OpenSession()) {
book = session.Query().ToList()
return View(book);
}
}
Далее создадим строго типизированнное представление (View) в котором отобразим все записи из книг. (RClick на красную надпись View (book)→Add View). Ставим галочки и выбираем следующие параметры, как на рисунке снизу (чтобы в Model Class можно выбрать из списка Модель Book, билдим проект Build→Build Solution).
Отобразится автоматически сгенерированный код, в которой отображаются все поля класса Book. После создания представления, запустим проект (F5). Отобразиться пустая страница.
Но если открыть SQL Server Manager Studio и посмотреть в БД Biblioteca, то там появится таблица Book. Заполним её данными.
(Можно изменить столбцы, к примеру, Description сделать из nVarChar (255) в text или NVarChar (Max)).
После этого обновите страницу, которая будет выглядеть так, как на рисунке ниже.