Часть 2. СОЗДАНИЕ КЛАССОВ, МАППИНГОВ И ЗАПОЛНЕНИЕ БД

от автора

КЛАССЫ И МАППИНГИ
В основном будет код… и комментарии. И небольшое объяснение перед созданием таблиц. А то невероятно длинная статья получится.

Класс Книга

 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; }     //Жанр (Многие-ко-Многим)     //Почему ISet а не IList? Только одна коллекция (IList) может выбираться с помощью JOIN выборки, если нужно  более одной коллекции для выборки JOIN, то лучше их преобразовать в коллекцию ISet     public virtual ISet<Genre> Genres { get; set; }     //Серия (Многие-к-одному)     public virtual Series Series { get; set; }     //Мнение и другое (Один-к-одному)     public virtual Mind Mind { get; set; }     //Автор (Многие-ко-многим)     public virtual ISet<Author> Authors { get; set; }     //Заранее инициализируем (только для многие-ко-многим) чтобы исключение null не возникало.     public Book() {         //Неупорядочное множество (в одной таблице не может присутствовать две точь-в-точь одинаковые строки, в противном случае выбирает одну, а другую игнорирует)         Genres = new HashSet<Genre>();         Authors = new HashSet<Author>();     } } //Маппинг класса Book public class BookMap : ClassMap<Book> {     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);         //Отношение многие-ко-многим         HasManyToMany(x => x.Genres)         //Правила каскадирования All - Когда объект сохраняется, обновляется или удаляется, проверяются и         //создаются/обновляются/добавляются все зависимые объекты         .Cascade.All()         //Название промежуточной таблицы ДОЛЖНО быть как и у класса Genre!         .Table("Book_Genre");         HasManyToMany(x => x.Authors)         .Cascade.All()         .Table("Book_Author");         //Отношение многие к одному         References(x => x.Series);         //Отношение один-к-одному. Главный класс.         HasOne(x => x.Mind).Cascade.All();     } } 

Класс Автор

 public class Author {        public virtual int Id { get; set; }         //Имя-Фамилия         public virtual string Name { get; set; }         //Биография        public virtual string Biography { get; set; }        //Книжки        public virtual ISet<Book> Books { get; set; }        //Инициализация Авторов        public Author() {               Books=new HashSet<Book>();        } }  //Маппинг Автора public class AuthorMap : ClassMap<Author> {     public AuthorMap() {        Id(x => x.Id);        Map(x => x.Name);        Map(x => x.Biography);         //Отношение многие-ко-многим         HasManyToMany(x => x.Books)        //Правила каскадирования All - Когда объект сохраняется, обновляется или удаляется, проверяются и создаются/обновляются/добавляются все зависимые объекты        .Cascade.All()        //Владельцем коллекции явл. другой конец отношения (Book) и он будет сохранен первым.        .Inverse()        //Название промежуточной таблицы ДОЛЖНО быть как и у класса Book!         .Table("Book_Author");      } } 

Класс Жанр

 public class Genre { public virtual int Id { get; set; }        //Название жанра        public virtual string Name { get; set; }        //Английское название жанра        public virtual string EngName { get; set; }        //Книжки        public virtual ISet<Book> Books { get; set; }        //Инициализация книг        public Genre() {               Books=new HashSet<Book>();        } } //Маппинг жанра public class GenreMap : ClassMap<Genre> {     public GenreMap() {        Id(x => x.Id);        Map(x => x.Name);        Map(x => x.EngName);        //Отношение многие-ко-многим        HasManyToMany(x => x.Books)        //Правила каскадирования All - Когда объект сохраняется, обновляется или удаляется, проверяются и создаются/обновляются/добавляются все зависимые объекты        .Cascade.All()        //Владельцем коллекции явл. другой конец отношения (Book) и он будет сохранен первым.        .Inverse()        //Название промежуточной таблицы ДОЛЖНО быть как и у класса Book!        .Table("Book_Genre");     } } 

Класс Мнение:

 public class Mind {        public virtual int Id { get; set; }        //Мое мнение        public virtual string MyMind { get; set; }        //Мнение фантлаба        public virtual string MindFantLab { get; set; }        //Книга        public virtual Book Book { get; set; } } //Маппинг Мind public class MindMap:ClassMap<Mind> {     public MindMap() {        Id(x => x.Id);        Map(x => x.MyMind);        Map(x => x.MindFantLab);        //Отношение один к одному        HasOne(x => x.Book).        //Дочерний (дополняющий класс) сохраняется вторым        Constrained();     } } 

Класс Цикл(Серия):

 public class Series {        public virtual int Id { get; set; }        public virtual string Name { get; set; }     //Я создал IList, а не ISet, потому что кроме Book, Series больше ни с чем не связана, хотя можно сделать и ISet        public virtual IList<Book> Books { get; set; }      //Инициализация книг.        public Series() {               Books = new List<Book>();        } } public class SeriesMap : ClassMap<Series> {        public SeriesMap() {              Id(x => x.Id);              Map(x => x.Name);              //Отношение один-ко-многим              HasMany(x => x.Books)              ////Владельцем коллекции явл. другой конец отношения (Book) и он будет сохранен первым.              .Inverse()              //Правила каскадирования All - Когда объект сохраняется, обновляется или удаляется, проверяются и              //создаются/обновляются/добавляются все зависимые объекты              .Cascade.All();        } } 

Если сейчас запустить проект и посмотреть БД Bibilioteca, то появятся новые таблицы с уже сформированными связями.

Небольшое объяснение
Nhibernate сохраняет в базу данных таблицу (главную), а затем все связи к ней. Inverse в ClassMap указывает, что таблица, с которой у него связь, должна сохраниться первой. Cascade.All означает выполнение каскадных операций при save-update и delete. (Ps. Можно прописать вместо Cascade.All -> .Cascade.SaveUpdate().Cascade.Delete())

Далее заполним эти таблицы данными.

Таблица Series

Id Name
1 Метро
2 Сталкер

Таблица Book

Id Name Description MfRaiting PageNumber Image IncomeDate Series_id
1 Метро 2033 Двадцать лет спустя Третьей мировой войны последние… 7 650 metro2033.png 2011-06-07 00:00:00.000 1
2 Метро 2034 …2034 год. Весь мир разрушен ядерной войной. Крупные… 8 350 metro2034.png 2012-07-15 00:00:00.000 1
3 Сталкер: Москва Сталкеров Чтобы быть сталкером, не обязательно ездить в Чернобыль… 8 200 empty.png 2011-07-19 00:00:00.000 2

Таблица Author

Id Name Description
1 Дмитрий Глуховский NULL
2 Ольга Чередниченко NULL
3 Артур Шигапов NULL

Таблица Book_Author

Author_id Book_id
1 1
1 2
2 3
3 3

Таблица Genre

Id Name EngName
1 Постапокалипсис NULL
2 Антиутопия NULL

Таблица Book_Genre

Book_id Genre_id
1 1
2 1
3 1
2 2

Таблица Mind

Id MyMind MindFantLab
1 Мистическое постапокалипсисное метро NULL
2 Не читал, так как там не было Артем NULL
3 Не читал NULL

ссылка на оригинал статьи http://habrahabr.ru/post/264961/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *