Приложение My Photos ASP.NET MVC 4.0 2014 Цель 1. Разработать модель и базовую функциональность ASP.NET MVC приложения. 2. Ознакомиться с управлением генерацией базы данных. 2 Фотоальбом • Приложение позволяет вести личную коллекцию фотографий. • Фотографии распределены по альбомам. Одна фотография может находиться в одном или нескольких альбомах. • Помимо изображения, фотография имеет название, дату и не структурированное текстовое описание. • Пользователи приложения могут просматривать чужие альбомы и оставлять отзывы о фотографиях. • Все пользователи приложения проходят регистрацию. При входе в приложение они вводят имя и пароль. 3 Другие темы для разработки Аукцион • Есть два типа пользователей – администратор и покупатели. Администратор выставляет вещи для продажи, назначает первоначальную цену и подтверждает покупку. Покупатель просматривает вещи, торгуется и получает извещение о том, что вещь продана ему или не ему. Книжный магазин • Есть два типа пользователей – администратор и покупатели. Администратор выкладывает книги, разделяя их по жанрам. Покупатель осуществляет поиск книги, кладет ее в корзину и подтверждает покупку. Покупатель может оставлять отзывы о ранее купленных книгах и читать отзывы других покупателей. Сайт голосования • Администратор выкладывает формы для голосования, и просматривает результаты. Форма представляет собой вопрос с несколькими предопределенными ответами. Голосующий просматривает открытые формы и выбирает ответ, за который он голосует. Он может видеть результаты тех голосований, в которых принял участие. Художественный музей • Есть музей с залами и картинами в залах. О залах известно: название, о картинах – название, автор, год. Посетители посещают залы, осматривают экспозицию и пишут отзывы о картинах. Могут выполнять поиск картины по фрагменту названия, фамилии художника, диапазону лет и любой комбинации этих признаков. Чтобы писать отзывы, посетитель должен пройти процедуру аутентификации, а если надо, то и регистрации. Администраторы (зарегистрированные пользователи) манипулируют залами и картинами, модерируют отзывы посетителей. 4 Еще темы •Простая социальная сеть. Регистрация пользователей. Настройка персональной информации. «Друзья» пользователя. Обмен сообщений с другими пользователями. Поиск пользователей по определенным критериям. Управление пользователями. Модерирование сообщений.[1] •Интернет-фотоальбом. Регистрация, загрузка фотографий. Возможность просматривать и оценивать фотографии других пользователей. Поиск фотографий. Управление пользователями. •Персональный блог. Регистрация пользователей. Создание блога (блогов). Создание и редактирование статей блога. Тэги статей. Поиск по тэгам, тексту. Комментирование статей. Управление пользователями. Модерирование статей и комментариев. •Интернет-аукцион. Просмотр, поиск, и «покупка» лотов. Регистрация и выставление лотов на аукцион. Управление пользователями и модерирование списка лотов. •Система тестирования знаний. Регистрация, выбор (поиск) теста. Прохождение теста с контролем времени. Статистика тестирования. Управление пользователями. Редактирование тестов. Расширенная статистика тестирования. •Файловое хранилище. Доступ к файлу по короткой ссылке. Общие файлы и файлы с ограниченным доступом. Для зарегистрированных пользователей – возможность размещения файлов и управление файлами. Управление пользователями и их файлами. Поиск файлов. •Картотека текстовых материалов (вариант: аудио или видео). Поиск в картотеке по различным критериями. Оценка материалов пользователями. •Система учета знаний. Зарегистрированные пользователи («программисты») указывают и оценивают свои знания в различных (сгруппированных) областях. Пользователь - «менеджер» осуществляет отбор программистов по заданным критериям. Возможность генерирования отчетов. Управление пользователями и ролями. Управления списками областей знаний. •Система отслеживания заданий. Выдача задания менеджером. Статус задания, согласно рабочему процессу. Процент выполнения. Почтовые уведомления клиентам системы. Управление пользователями и их ролями. • Форум. Стандартные операции, присущие любому форуму – добавление тем, сообщений. Модерирование записей. Работа с пользователями форума. 5 Порядок работы над проектом 1. Сформулировать требования к приложению. 2. Разработать пользовательский интерфейс и карту сайта. Сделать эскизы страниц. 3. Разработать модель данных (классы). 4. Поэтапно наращивать функциональность в таком порядке: дополнить модель, добавить контроллер, добавить представление. 6 Требования к приложению • • • • • • Пользователь может создавать и удалять альбомы. Пользователь может добавлять и удалять фотографии из альбома. Пользователь может просматривать чужие альбомы. Пользователь может оставлять отзывы о чужих фотографиях. Пользователь может зарегистрировать другого пользователя, внеся в базу его имя и пароль. Пользователь может пройти процедуру аутентификации путем ввода имени и пароля. 7 Карта сайта Список альбомов друга Список своих альбомов и список друзей Фото из одного альбома друга Фото из одного своего альбома Страница отзывов о фотографии Страница отзывов о фотографии 8 Начало работы над приложением 1. 2. 3. 4. 5. 6. 7. В Студии 2013 создать пустой проект с файлами MVC. В папку Models добавить классы модели. В папку DAL добавить класс-наследник DbContext. Прописать строку соединения в web.config Установить пакет: PM> Install-Package EntityFramework Создать HomeController с методом Index для показа всех фотографий. Добавить типизированное представление для метода Index. 9 Классы модели class User: Id: Int Name: String --Albums: List<Album> class Album: Id: Int UserId Name: string --Photos: List<Photo> public class User { public int Id { get; set; } public string Name { get; set; } public string Password { get; set; } // public virtual ICollection<Album> Albums { get; set; } } public class Album { public int Id { get; set; } public int UserId { get; set; } public string Name { get; set; } // public User User { get; set; } public virtual ICollection<Photo> Photos { get; set; } public Album() { Photos = new List<Photo>(); } } class Photo: Id: Int UserId Image: byte[] Title: string Moment: DateTime --Albums: List<Album> public class Photo { public int Id { get; set; } public int UserId { get; set; } public string Title { get; set; } public DateTime Moment { get; set; } public byte[] Image { get; set; } // public virtual ICollection<Album> Albums { get; set; } public Photo() { Albums = new List<Album>(); } } 10 Класс контекста public class Repository: DbContext { public DbSet<User> Users { get; set; } public DbSet<Album> Albums { get; set; } public DbSet<Photo> Photos { get; set; } } 11 Управление генерацией БД Соглашения Атрибуты Fluent API 12 Соглашение: Первичный ключ • Свойство является первичным ключом, если свойство называется Id или <class_name>Id. • Если первичный ключ имеет тип int, long или short, он делается автоинкрементным. public class User { public int Id { get; set; } public string Name { get; set; } public string Password { get; set; } // public virtual ICollection<Album> Albums { get; set; } } 13 Соглашение: Бинарные отношения • Отношение определяется как бинарное, если у двух классов обнаруживаются свойства или свойства-коллекции с типом противоположного класса. public class User { public int Id { get; set; } public string Name { get; set; } public string Password { get; set; } // public virtual ICollection<Album> Albums { get; set; } } public class Album { public int Id { get; set; } public int UserId { get; set; } public string Name { get; set; } // public User User { get; set; } public virtual ICollection<Photo> Photos { get; set; } public Album() { Photos = new List<Photo>(); } } 14 Соглашение: Внешний ключ Для определения имени свойства, которое поставляет значения внешнего ключа 1) <navigation property name><primary key property name> (например, UserId), 2) <principal class name><primary key property name> (например, UserId), 3) <primary key property name> (например, Id из класса User). public class User { public int Id { get; set; } public string Name { get; set; } public string Password { get; set; } // public virtual ICollection<Album> Albums { get; set; } } public class Album { public int Id { get; set; } public int UserId { get; set; } public string Name { get; set; } // public User User { get; set; } public virtual ICollection<Photo> Photos { get; set; } У таблицы Album будет внешний ключ. Свойство класса Album, которое поставляет значения внешнего ключа – UserId. public Album() { Photos = new List<Photo>(); } } 15 Атрибуты аннотации данных [Key] Свойство входит с состав первичного ключа сущности [Column] Атрибут свойства для указания имени столбца, ординарного типа и типа данных [ForeignKey] Ставится на навигационное свойство и задает имя скалярного свойства – источник значений внешнего ключа. [NotMapped] Атрибут свойства или класса для его исключения из базы данных [Table] Атрибут класса для указания имени таблицы и схемы [ConcurrencyCheck] Свойство участвует в контроле оптимистической блокировки [DatabaseGenerated] Указывает, как база данных будет вычислять значение поля (Identity, Computed or None) [InverseProperty] Отмечает навигационное свойство, которое представляет другой конец отношения. Используется, например, при автоссылках. 16 Применение аннотаций данных public class User { [Key] public int Id { get; set; } [Column] public string Name { get; set; } [Column] public string Password { get; set; } // public virtual ICollection<Album> Albums { get; set; } } public class Album { [Key] public int Id { get; set; } [Column] public int UserId { get; set; } [Column] public string Name { get; set; } // [ForeignKey("UserId")] public User User { get; set; } public virtual ICollection<Photo> Photos { get; set; } public Album() { Photos = new List<Photo>(); } } 17 Fluent API В обработчике события ModelCreating можно управлять генерацией и задать инициализатор для сгенерированной базы данных. public class Repository: DbContext { public DbSet<User> Users { get; set; } public DbSet<Album> Albums { get; set; } public DbSet<Photo> Photos { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Управление генерацией ... // Назначение инициализатора Database.SetInitializer(new Initializer()); } } 18 Управление генерацией protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Отношение "многие ко многим" между таблицами Albums и Photos. modelBuilder.Entity<Album>(). HasMany(a => a.Photos). WithMany(p => p.Albums). Map( m => { m.MapLeftKey("AlbumId"); m.MapRightKey("PhotoId"); m.ToTable("AlbumPhotos"); }); // Ограничение "NOT NULL" и ограничение длины строки для столюца User.Name modelBuilder.Entity<User>() .Property(p => p.Name) .IsRequired().HasMaxLength(50); Database.SetInitializer(new Initializer()); } Другие примеры использования Fluent API можно найти в http://blog.vkuznetsov.ru/posts/2011/07/31/code-first-v-entity-framework-41-primery-ispolzovaniya-fluent-api19 Инициализация базы данных public class Initializer : IDatabaseInitializer<Repository> { public void InitializeDatabase(Repository context) { if (!context.Database.Exists() ) { context.Database.Delete(); context.Database.Create(); context.Database.ExecuteSqlCommand( "ALTER TABLE Users ADD UNIQUE (Name)"); context.Database.ExecuteSqlCommand( "INSERT INTO Users (Name, Password) VALUES ('User1', '@User1')"); context.Database.ExecuteSqlCommand( "INSERT INTO Users (Name, Password) VALUES ('User2', '@User2')"); } } } 20 Миграция изменений модели Для синхронизации модели со схемой базы данных имеется механизм миграций с тремя командами: • Enable-Migrations – создается каталог Migrations, в котором будет накапливаться программный код миграций. • Add-Migration имя_класса_контекста – добавляется код последней миграции • Update-Database – вносятся изменения в базу данных 21 Слой доступа к данным Методы доступа данных можно разместить в клаcсе Repository или в частичном классе Repository. Чтобы увидеть сгенерированную команду SQL to Entity, достаточно вызвать метод ToString() для запроса. 22 Самостоятельно 1. Выбрать тему учебного проекта. 2. Разработать модель данных. 3. Сгенерировать схему в базе данных. 4. Реализовать слой доступа к данным по шаблону "Репозиторий". 5. Реализовать упрощенную схему аутентификации и главную страницу сайта (список альбомов). 23 Team Foundation Services • Зарегистрироваться на TFServises https://tfs.visualstudio.com/ • Создать проект и команду • Заполнить Backlog задачами • Выбрать задачи для очередного спринта • Спланировать спринт 24