Дата изменения: 12.10.2017

Поход, называемый Code First (сначала код) предполагает минимальное участие в проектировании сущностей базы данных программистом. Он просто пишет код, остальное делает Entity и Visual Studio.

Он подходит в случаях если главное в проекте – бизнес логика, а база данных – это способ хранения данных. Или в случаях если проект уже написан, но в качестве источников данных использованы списки, массивы, коллекции. Code First позволяет с минимальными усилиями изменить проект с использованием баз данных в качестве источников данных вместо стандартных коллекций .NET.

Мы создадим веб приложение использующее базу данных многоквартирного дома. В Основе его будут две модели: жильцы и квартиры.

Создание веб приложения

Первый шаг - создание проекта:

  1. Откройте Visual Studio и создайте новый проект с именем EnrollmentApp
    Создание нового проекта в VisualStudio EnrollmentApp
  2. Выберите шаблон MVC, уберите аутентификацию (кнопка изменить проверку подлинности) и нажмите создать проект.
    Выбор шаблона MVC

 

Когда проект будет создан подключите к нему Entity.

Создание классов модели

Работа с Entity при подходе Code First начинается с создания типов данных. Типом, описывающим жильца будет класс Tenant, описывающим квартиру – класс Apartment.

Создайте в папке Models проекта соответствующие файлы классов и определите их как показано ниже:

 

Файл Tenant.cs:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


namespace EnrollmentApp.Models
{
    [Table("Tenants")] // Таблица в базе данных будет называется Tenants
    public class Tenant
    {
        [Key] // Явное указание через атрибут, что свойство ID должно быть первичным ключом в таблице Tenants
        public int ID { get; set; } // свойство для первичного ключа.
        public string LastName { get; set; } // Фамилия жильца.
        public string FirstAndMidName { get; set; } // Имя и отчество жильца.
        public DateTime RegistrationDate { get; set; } // Дата регистрации жильца.
    }
}

 

Файл Apartment.cs:

 

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


namespace EnrollmentApp.Models
{
    [Table("Apartments")]
    public class Apartment
    {
        [Key]
        public int ApartmentID { get; set; }   // Идентификатор (будет первичным ключом)
        public decimal ApartСost { get; set; } // Стоимость квартиры.
        public int ApartNumber { get; set; }   // Номер квартиры.
        public int NumberofRooms { get; set; } // Количество комнат в квартире.

        public virtual ICollection<Tenant> Tenants { get; set; } // Список жильцов, зарегистрированных в этой квартире.

    }
}

Оба класса будут преобразованы в наборы данных, то есть таблицы базы данных с помощью Entity. Их свойства станут столбцами таблиц. Значение этих свойств значениями в строках.

 Чтобы Entity понял, как преобразовать тип C# в тип базы данных, мы при определении должны следовать нескольким правилам:

  • все свойства должны быть открытыми (public);
  • свойство, которое должно стать первичным ключом таблицы должно иметь имя ID, либо его имя должно оканчиваться на ID (CustomerID, BisnessID, ApartmentID)
  • если нужно пометить свойство как первичный ключ будущей сущности, но его имя не содержит ID, то сделайте это с помощью атрибута [Key];
  • если класс не содержит ни одного свойство содержащего в имени ID, Entity сам добавит такой столбец, имя этого столбца будет совпадать с именем таблицы.

Кроме обычных свойств классы моделей могут содержать виртуальные свойства. Они становятся навигационными свойствами при преобразовании в модель EDX. Навигационные свойства характеризуют связь между таблицами.

В нашем случае это связь один ко многим – несколько жильцов могут быть зарегистрированы в одной квартире. Поэтому класс Apartment содержит внутренний массив экземпляров Tenant.

Создание контекста данных

Класс, который обеспечивает взаимодействие между классами-моделями и одноименными таблицами в базе данных называется контекстом.

Создавая контекст мы как бы говорим инфраструктуре: «Я не хочу разбираться в твоих API, дай мне простой инструмент манипуляции данными». Этот инструмент – контекст.

Контекст класс, наследуемый от System.Data.Entity.DbContext.

Он содержит:

  • строготипизированые открытые свойства DbSet;
  • один или несколько конструкторов.

Рекомендуемый Microsoft стиль – это создание контекста в отдельной папке проекта.

 

Создайте в проекте папку DAL (от Data Acsess Layer). Затем создайте в папке новый класс, назовите его RegistrationContext.cs и приведите его в соответствие с содержимым ниже:

 

RegistrationContext.cs

using System.Data.Entity; // DbContext определен здесь.
using EnrollmentApp.Models;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace EnrollmentApp.DAL
{
    public class RegistrationContext : DbContext // Наследуем от DbContext
    {
        public RegistrationContext():base("RegistrationContext") // Вызываем из конструктора базовый конструктор с параметром – именем будущей базы данных.
        {

        }
        public DbSet<Tenant> Tenants { get; set; } // Открытое свойство. Для доступа к таблице Tenants в базе данных.
        public DbSet<Apartment> Apartments { get; set; } // Аналогичное открытое свойство для доступа к таблице Apartments
       
    }
}

Строка подключения

После создания контекста нужно добавить в приложение строку подключения БД.

Строка подключения – это описание нескольких параметров:

  • имя базы данных;
  • где расположены ее файлы;
  • кто ее поставщик;
  • режим подключения.

Указать строку подключения можно несколькими способами:

  1. В файле web.config.
  2. В конструкторе.

В нашем приложении мы будем использовать локальную базу данных. Локальные базы данных расположены на локальных серверах, то есть расположены на той же машине с которой запускается приложение. Сервер, который управляет локальными базами MS SQL Server Express, он встроен в Visual Studio.

Однако, в реальных приложениях такой подход не годится. MS SQL Server Express не умеет работать с ISS.

 

В файле web,config строка подключения должна быть вписана внутри тега <configurations> перед тегом <appsettings>

На листинге ниже выделена серым цветом. Располагается внутри тега 

<connectionStrings>
configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name ="RegistrationContext" connectionString ="Data Source=(LocalDb)MSSQLLocalDB;Initial Catalog=EnrollmentApp.mdf;Integrated Security=True;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
   <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>

Если вы не впишите строку подключения в файл web.config, то компилятор будет искать ее в параметре конструктора контекста.

 

public RegistrationContext():base("RegistrationContext") // параметр указывает на имя БД.
 {

 }

Для локальных БД достаточно только имени БД. Для удаленных нужно вписывать полную строку.

 

Все о строках подключения читайте в официальной документации Microsoft.

 

Сайт с шаблонами для срока подключения к базам данных разных производителей смотрите на сайте https://www.connectionstrings.com

После создания строки подключения Entity ничего больше от вас не нужно. Она знает какие типы вы храните в базе из контекста. Из строки подключения знает где располагается база и какой у нее провайдер.

Осталось достроить веб приложение создав для него бизнес логику и логику представлений

Создание контроллера и представлений

Бизнес логика контроллера в MVC приложения традиционно лежит на плечах контроллера, логика представлений – на представлениях.

Создать ее автоматически на основе моделей вы можете, использовав шаблон в Visual Studio.

Для этого:

  1. Щелкните правой кнопкой на папке Сontrollers в проекте. Выберите Добавить(Add) -Контроллер.
  2. Выберите шаблон Контроллер MVC 5 c использованием Entity Framework.

В выпадающем списке «класс контекста» выберите созданный вами контекст (RegistrationContext), в списке «класс модели» укажите класс Tentant. Галочки оставьте по умолчанию.

Создание контроллера в VisualStudio

После нажатия кнопки добавить Visual Studio на создаст вам контроллер с методами действия для каждой возможно операцией с базой данных. Мы рассмотрим их на следующих уроках.

Главное, что все они работают на основе контекста, объект которого создается в классе контроллера:

public class TenantController : Controller
{
  private RegistrationContext db = new RegistrationContext();
//…
}

Поиск:

Tenant tenant = db.Tenants.Find(id);

Добавление элемента:

Tenant tenant = db.Tenants.Add(tenant);

Удаление:

Tenant tenant = db.Tenants.Find(id);
            db.Tenants.Remove(tenant);

А так сохраняются изменения после каждой операции:

db.SaveChanges();

Все операции на основе объекта контекста.

Создание инициализатора

Entity может автоматически создать, удалить или произвести любые изменения с базой данных, когда приложение запускается. Инициализатор – это блок кода, который указывает, что должно быть сделано с базой, когда приложение только запустилось.

Очевидно, что, если приложение запущено в первый раз, в базе нет никаких данных. Это можно исправить, добавив в инициализатор логику добавления в базу первичных данных. Их затем можно удалить, изменить или добавить новые.

Инициализатор, как и контекст просто класс. Часть общей логики DAL (Data Access Layer)

С помощью средств Visual Studio добавьте в папку DAL (в ту же, где вы создавали контекст) новый класс с названием EnrollmentInitializer.cs

Содержание файла EnrollmentInitializer.cs:

 

EnrollmentInitializer.cs

 

using System;
using System.Collections.Generic;
using EnrollmentApp.Models;

namespace EnrollmentApp.DAL
{
    public class EnrollmentInitializer: System.Data.Entity.DropCreateDatabaseIfModelChanges<RegistrationContext>
    {
        protected override void Seed(RegistrationContext context)
        {
            var Tenants = new List<Tenant> // Заполняем список
            {
                new Tenant{FirstAndMidName =  "Александр Васильевич", LastName = "Кузьмин", RegistrationDate = DateTime.Parse("2007-11-02")},
                new Tenant{FirstAndMidName =  "Захира Кулебяковна", LastName = "Кузьмина", RegistrationDate = DateTime.Parse("2007-12-31") },
                new Tenant{FirstAndMidName =  "Эльвира Фывовна", LastName = "Дягтерева", RegistrationDate = DateTime.Parse("2012-06-05") },
                new Tenant{FirstAndMidName =  "Владимир Владимирович", LastName = "Вяземский", RegistrationDate = DateTime.Parse("2001-09-07")},
                new Tenant{FirstAndMidName =  "Илья Максимович", LastName = "Ильячев", RegistrationDate = DateTime.Parse("1999-06-09") },
                new Tenant{FirstAndMidName =  "Субмарина Атомовна", LastName = "Подлодкина", RegistrationDate = DateTime.Parse("1995-07-17") },
                new Tenant{FirstAndMidName =  "Михаил Сергеевич", LastName = "Александров", RegistrationDate = DateTime.Parse("2005-10-15")},
                new Tenant{FirstAndMidName =  "Генадий Андреевич", LastName = "Лужков", RegistrationDate = DateTime.Parse("2003-09-25") },
                new Tenant{FirstAndMidName =  "Лариса Павловна", LastName = "Лужкова", RegistrationDate = DateTime.Parse("2007-02-02") },
            };
            Tenants.ForEach(t => context.Tenants.Add(t)); // Добавляем все элементы списка через контекст.
            context.SaveChanges(); // Сохраняем изменения.

            var Apartments = new List<Apartment>
            {
                new Apartment{Apartnumber = 1, ApartСost = 20000, NumberofRooms = 2  },
                new Apartment{Apartnumber = 2, ApartСost = 30000, NumberofRooms = 2  },
                new Apartment{Apartnumber = 3, ApartСost = 25000, NumberofRooms = 2  },
                new Apartment{Apartnumber = 4, ApartСost = 28000, NumberofRooms = 2  },
                new Apartment{Apartnumber = 5, ApartСost = 22000, NumberofRooms = 2  },
                new Apartment{Apartnumber = 6, ApartСost = 23400, NumberofRooms = 2  },
                new Apartment{Apartnumber = 7, ApartСost = 31000, NumberofRooms = 3  },
                new Apartment{Apartnumber = 8, ApartСost = 44000, NumberofRooms = 3  },
                new Apartment{Apartnumber = 10, ApartСost = 19000, NumberofRooms = 2  },
                new Apartment{Apartnumber = 11, ApartСost = 43000, NumberofRooms = 4  },
            };

            Apartments.ForEach(a => context.Apartments.Add(a));
            context.SaveChanges();
        }
    }
}

В классе реализован единственный метод Seed, который принимает параметром контекст данных. Мы добавляет элементы список. А затем списки по элементной -  таблицу посредством объекта контекста.

Итог

Приложение готово. Вы можете отшлифовать его, пройдясь по представлениям, настроив поля ввода, изменив домашнюю страницу.

Главное, чего мы добились – это сохранения в базу и извлечение из нее простыми средствами.

Чтобы просмотреть, что после запуска приложения у вас оказалось в базе.

  • Закройте браузер и прервите выполнение приложения;
  • Откройте окно обозреватель серверов и внутри пункта подключение данных строчку с названием вашего контекста (RegistrationContext). Раскройте этот пункт.
    Обозреватель серверов в VisualStudio
  • Щелкните правой кнопкой на интересующей вас таблице и выберите пункт «показать таблицу данных»

Таблица данных

 

 

 

Данный материал был вам полезен?

Не забудьте оставить свой комментарий, а также поблагодарить автора и поддержать его для создания новых полезных материалов

Наверх