[Из песочницы] Уроки по 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 — правая кнопка)

92f3ddeeeb394a4285e3b71dfa06f421.jpg

Далее запускаем Nuget Package (Tools→Library Package Manager→Package Manager Console). Прописываем следующую строку: Install-Package FluentNHibernate. Нажимаем Enter, и ждем завершения установки FluentNHibernat’a.

a3444cb43ca34b31a872041a1745ba48.png

Если нужно установить определенную версию FluentNhibernate, то ищем строку на сайте NuGet www.nuget.org/packages/FluentNHibernate/2.0.1 в таблице Version.
1.2 Настройка FluentNHibernate

  1. Откроем БД SQL Server Manager и создадим там БД «Biblioteca»
  2. Откроем Visual Studio, в папке «Models» создадим класс «Book.cs» (Models→Book.cs)
  3. Создаем в 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.

e82493d4f77d43d1ae4d96b10f5b70c6.png

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).

daebfc2b348240c7b14d08170cae3558.png

Отобразится автоматически сгенерированный код, в которой отображаются все поля класса Book. После создания представления, запустим проект (F5). Отобразиться пустая страница.

Но если открыть SQL Server Manager Studio и посмотреть в БД Biblioteca, то там появится таблица Book. Заполним её данными.

e94a6144969c436ea571a31c462420dc.png

(Можно изменить столбцы, к примеру, Description сделать из nVarChar (255) в text или NVarChar (Max)).

3b66f9adedd1475abb56c1d751f3e5ee.png

После этого обновите страницу, которая будет выглядеть так, как на рисунке ниже.

308c3255d57b4c6499cd1a3a21919c20.png

© Habrahabr.ru