Руководство. Начало работы с Entity Framework 6 Code First с помощью MVC 5Tutorial: Get Started with Entity Framework 6 Code First using MVC 5

Note

Для новой разработки рекомендуется ASP.NET Core Razor Pages с контроллерами и ПРЕДСТАВЛЕНИЯМИ MVC ASP.NET.For new development, we recommend ASP.NET Core Razor Pages over ASP.NET MVC controllers and views. Серию руководств, аналогичную этой, с помощью Razor Pages см. в разделе Учебник. Начало работы с Razor Pages в ASP.NET Core.For a tutorial series similar to this one using Razor Pages, see Tutorial: Get started with Razor Pages in ASP.NET Core. Новое руководство:The new tutorial:

  • проще для выполнения;Is easier to follow.
  • содержит больше рекомендаций по EF Core;Provides more EF Core best practices.
  • использует более эффективные запросы;Uses more efficient queries.
  • более актуально, так как используются новейшие API;Is more current with the latest API.
  • охватывает дополнительные возможности;Covers more features.
  • является предпочтительным подходом для разработки новых приложений.Is the preferred approach for new application development.

В этой серии руководств вы узнаете, как создать приложение ASP.NET MVC 5, которое использует Entity Framework 6 для доступа к данным.In this series of tutorials, you learn how to build an ASP.NET MVC 5 application that uses Entity Framework 6 for data access. В этом руководстве используется рабочий процесс Code First.This tutorial uses the Code First workflow. Сведения о выборе между Code First, Database First и Model First см. в разделе Создание модели.For information about how to choose between Code First, Database First, and Model First, see Create a model.

В этой серии руководств объясняется, как создать пример приложения университета Contoso.This tutorial series explains how to build the Contoso University sample application. Пример приложения — это простой веб-сайт университета.The sample application is a simple university website. С его помощью можно просматривать и обновлять сведения об учащихся, курсах и преподавателях.With it, you can view and update student, course, and instructor information. Ниже приведены два создаваемых экрана.Here are two of the screens you create:

Students_Index_page

Изменить учащийся

Изучив это руководство, вы:In this tutorial, you:

  • Создание веб-приложения MVCCreate an MVC web app
  • Настройка стиля сайтаSet up the site style
  • Установка Entity Framework 6Install Entity Framework 6
  • Создание модели данныхCreate the data model
  • Создание контекста базы данныхCreate the database context
  • Инициализация базы данных с тестовыми даннымиInitialize DB with test data
  • Настройка EF 6 для использования LocalDBSet up EF 6 to use LocalDB
  • Создание контроллера и представленийCreate controller and views
  • Просмотр базы данныхView the database

предварительные требованияPrerequisites

Создание веб-приложения MVCCreate an MVC web app

  1. Откройте Visual Studio и создайте C# веб-проект с помощью шаблона веб-приложения ASP.NET (.NET Framework) .Open Visual Studio and create a C# web project using the ASP.NET Web Application (.NET Framework) template. Присвойте проекту имя ContosoUniversity и нажмите кнопку ОК.Name the project ContosoUniversity and select OK.

    Диалоговое окно "Создание проекта" в Visual Studio

  2. В новом веб-приложении ASP.NET — ContosoUniversityвыберите MVC.In New ASP.NET Web Application - ContosoUniversity, select MVC.

    Диалоговое окно "Создание веб-приложения" в Visual Studio

    Note

    По умолчанию параметр authentication имеет значение без проверки подлинности.By default, the Authentication option is set to No Authentication. В этом руководстве для веб-приложения пользователи не должны входить в систему.For this tutorial, the web app doesn't require users to sign in. Кроме того, он не ограничивает доступ в зависимости от того, кто вошел в систему.Also, it doesn't restrict access based on who's signed in.

  3. Чтобы создать проект, щелкните ОК.Select OK to create the project.

Настройка стиля сайтаSet up the site style

Выполните незначительную настройку меню, макета и домашней страницы сайта.A few simple changes will set up the site menu, layout, and home page.

  1. Откройте Views\Shared\_layout. cshtmlи внесите следующие изменения:Open Views\Shared\_Layout.cshtml, and make the following changes:

    • Измените каждое вхождение «мое приложение ASP.NET» и «имя приложения» на «университет Contoso».Change each occurrence of "My ASP.NET Application" and "Application name" to "Contoso University".
    • Добавьте пункты меню для учащихся, курсов, преподавателей и отделов и удалите контактную запись.Add menu entries for Students, Courses, Instructors, and Departments, and delete the Contact entry.

    Изменения выделены в следующем фрагменте кода:The changes are highlighted in the following code snippet:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>@ViewBag.Title - Contoso University</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="navbar-inner">
                <div class="container">
                    <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Contoso University", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                    <div class="nav-collapse collapse">
                        <ul class="nav">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Students", "Index", "Student")</li>
                            <li>@Html.ActionLink("Courses", "Index", "Course")</li>
                            <li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
                            <li>@Html.ActionLink("Departments", "Index", "Department")</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    
        <div class="container">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; @DateTime.Now.Year - Contoso University</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
    
  2. В Views\Home\Index.cshtmlзамените содержимое файла следующим кодом, чтобы заменить текст о ASP.NET и MVC текстом, посвященным этому приложению:In Views\Home\Index.cshtml, replace the contents of the file with the following code to replace the text about ASP.NET and MVC with text about this application:

    @{
        ViewBag.Title = "Home Page";
    }
    
    <div class="jumbotron">
        <h1>Contoso University</h1>
    </div>
    <div class="row">
        <div class="col-md-4">
            <h2>Welcome to Contoso University</h2>
            <p>Contoso University is a sample application that
            demonstrates how to use Entity Framework 6 in an 
            ASP.NET MVC 5 web application.</p>
        </div>
        <div class="col-md-4">
            <h2>Build it from scratch</h2>
            <p>You can build the application by following the steps in the tutorial series on the ASP.NET site.</p>
            <p><a class="btn btn-default" href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/">See the tutorial &raquo;</a></p>
        </div>
        <div class="col-md-4">
            <h2>Download it</h2>
            <p>You can download the completed project.</p>
            <p><a class="btn btn-default" href="https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip">Download &raquo;</a></p>
        </div>
    </div>
    
  3. Нажмите клавиши CTRL + F5, чтобы запустить веб-сайт.Press Ctrl+F5 to run the web site. Домашняя страница отображается в главном меню.You see the home page with the main menu.

Установка Entity Framework 6Install Entity Framework 6

  1. В меню Сервис выберите Диспетчер пакетов NuGet, а затем выберите консоль диспетчера пакетов.From the Tools menu, choose NuGet Package Manager, and then choose Package Manager Console.

  2. В окне Консоль диспетчера пакетов введите следующую команду:In the Package Manager Console window, enter the following command:

    Install-Package EntityFramework
    

Этот шаг состоит из нескольких шагов, которые можно выполнить в этом руководстве вручную, но это могло быть сделано автоматически с помощью функции формирования шаблонов ASP.NET MVC.This step is one of a few steps that this tutorial has you do manually, but that could have been done automatically by the ASP.NET MVC scaffolding feature. Их можно выполнить вручную, чтобы увидеть шаги, необходимые для использования Entity Framework (EF).You're doing them manually so that you can see the steps required to use Entity Framework (EF). Позднее формирование шаблонов будет использоваться для создания контроллера и представлений MVC.You'll use scaffolding later to create the MVC controller and views. Альтернативой является возможность формирования шаблонов автоматически устанавливать пакет EF NuGet, создать класс контекста базы данных и создать строку подключения.An alternative is to let scaffolding automatically install the EF NuGet package, create the database context class, and create the connection string. Когда все будет готово, все, что нужно сделать, — пропустить эти шаги и сформировать шаблон контроллера MVC после создания классов сущностей.When you're ready to do it that way, all you have to do is skip those steps and scaffold your MVC controller after you create your entity classes.

Создание модели данныхCreate the data model

Теперь необходимо создать классы сущностей для приложения университета Contoso.Next you'll create entity classes for the Contoso University application. Начнем с следующих трех сущностей:You'll start with the following three entities:

Курс <-> регистрации <-> учащийсяCourse <-> Enrollment <-> Student

СущностиEntities СвязьRelationship
Курс регистрацииCourse to Enrollment Один ко многимOne-to-many
Регистрация учащихсяStudent to Enrollment Один ко многимOne-to-many

Между сущностями Student и Enrollment, а также между сущностями Course и Enrollment существует отношение "один ко многим".There's a one-to-many relationship between Student and Enrollment entities, and there's a one-to-many relationship between Course and Enrollment entities. Другими словами, учащийся может быть зарегистрирован в любом количестве курсов, а в отдельном курсе может быть зарегистрировано любое количество учащихся.In other words, a student can be enrolled in any number of courses, and a course can have any number of students enrolled in it.

В следующих разделах вы создадите класс для каждой из этих сущностей.In the following sections, you'll create a class for each one of these entities.

Note

Если вы попытаетесь скомпилировать проект до завершения создания всех этих классов сущностей, вы получите ошибки компилятора.If you try to compile the project before you finish creating all of these entity classes, you'll get compiler errors.

Сущность StudentThe Student entity

  • В папке Models создайте файл класса с именем Student.CS , щелкнув правой кнопкой мыши папку в обозреватель решений и выбрав пункт Добавить > класс.In the Models folder, create a class file named Student.cs by right-clicking on the folder in Solution Explorer and choosing Add > Class. Замените код шаблона следующим кодом:Replace the template code with the following code:

    using System;
    using System.Collections.Generic;
    
    namespace ContosoUniversity.Models
    {
        public class Student
        {
            public int ID { get; set; }
            public string LastName { get; set; }
            public string FirstMidName { get; set; }
            public DateTime EnrollmentDate { get; set; }
            
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }
    

Свойство ID будет использоваться в качестве столбца первичного ключа в таблице базы данных, соответствующей этому классу.The ID property will become the primary key column of the database table that corresponds to this class. По умолчанию Entity Framework интерпретирует свойство с именем ID или classname ID в качестве первичного ключа.By default, Entity Framework interprets a property that's named ID or classname ID as the primary key.

Свойство Enrollments является свойством навигации.The Enrollments property is a navigation property. Свойства навигации содержат другие сущности, связанные с этой сущностью.Navigation properties hold other entities that are related to this entity. В этом случае свойство Enrollments сущности Student будет содержать все Enrollment сущности, связанные с этой сущностью Student.In this case, the Enrollments property of a Student entity will hold all of the Enrollment entities that are related to that Student entity. Иными словами, если данная строка Student в базе данных содержит две связанные Enrollment строки (строки, которые содержат значение первичного ключа учащегося в их StudentID внешнем ключевом столбце), то Student Enrollmentsной сущности будут содержать эти две Enrollment сущности.In other words, if a given Student row in the database has two related Enrollment rows (rows that contain that student's primary key value in their StudentID foreign key column), that Student entity's Enrollments navigation property will contain those two Enrollment entities.

Свойства навигации обычно определяются как virtual, чтобы они могли воспользоваться преимуществами определенных Entity Frameworkных функций, таких как Отложенная загрузка.Navigation properties are typically defined as virtual so that they can take advantage of certain Entity Framework functionality such as lazy loading. (Отложенная загрузка будет объяснена позже, в руководстве по чтению связанных данных далее в этой серии.)(Lazy loading will be explained later, in the Reading Related Data tutorial later in this series.)

Если свойство навигации может содержать несколько сущностей (как в отношениях "многие ко многим" или "один ко многим"), оно должно иметь тип списка, допускающий добавление, удаление и обновление записей, такой как ICollection.If a navigation property can hold multiple entities (as in many-to-many or one-to-many relationships), its type must be a list in which entries can be added, deleted, and updated, such as ICollection.

Сущность EnrollmentThe Enrollment entity

  • В папке Models создайте файл Enrollment.cs и замените существующий код следующим кодом:In the Models folder, create Enrollment.cs and replace the existing code with the following code:

    namespace ContosoUniversity.Models
    {
        public enum Grade
        {
            A, B, C, D, F
        }
    
        public class Enrollment
        {
            public int EnrollmentID { get; set; }
            public int CourseID { get; set; }
            public int StudentID { get; set; }
            public Grade? Grade { get; set; }
            
            public virtual Course Course { get; set; }
            public virtual Student Student { get; set; }
        }
    }
    

Свойство EnrollmentID будет первичным ключом; Эта сущность использует шаблон ID className вместо ID сама по себе, как показано в Student сущности.The EnrollmentID property will be the primary key; this entity uses the classname ID pattern instead of ID by itself as you saw in the Student entity. Как правило, следует выбирать один шаблон, который будет использоваться в рамках всей модели данных.Ordinarily you would choose one pattern and use it throughout your data model. В этом случае демонстрируется возможность использования любого из шаблонов.Here, the variation illustrates that you can use either pattern. В последующем учебнике вы узнаете, как использование ID без classname упрощает реализацию наследования в модели данных.In a later tutorial, you'll see how using ID without classname makes it easier to implement inheritance in the data model.

Свойство Grade является перечислением.The Grade property is an enum. Знак вопроса после объявления типа Grade указывает, что свойство Gradeдопускает значение NULL.The question mark after the Grade type declaration indicates that the Grade property is nullable. Оценка, имеющая значение null, отличается от нулевой — значение NULL означает, что категория не известна или еще не была назначена.A grade that's null is different from a zero grade — null means a grade isn't known or hasn't been assigned yet.

Свойство StudentID представляет собой внешний ключ. Ему соответствует свойство навигации Student.The StudentID property is a foreign key, and the corresponding navigation property is Student. Сущность Enrollment связана с одной сущностью Student, поэтому это свойство может содержать одну сущность Student (в отличие от представленного ранее свойства навигации Student.Enrollments, которое может содержать несколько сущностей Enrollment).An Enrollment entity is associated with one Student entity, so the property can only hold a single Student entity (unlike the Student.Enrollments navigation property you saw earlier, which can hold multiple Enrollment entities).

Свойство CourseID представляет собой внешний ключ. Ему соответствует свойство навигации Course.The CourseID property is a foreign key, and the corresponding navigation property is Course. Сущность Enrollment связана с одной сущностью Course.An Enrollment entity is associated with one Course entity.

Entity Framework интерпретирует свойство как свойство внешнего ключа, если оно называется <имя свойства навигации><имя свойства первичного ключа> (например, StudentID для свойства навигации Student, так как первичный ключ Student сущности ID).Entity Framework interprets a property as a foreign key property if it's named <navigation property name><primary key property name> (for example, StudentID for the Student navigation property since the Student entity's primary key is ID). Свойства внешнего ключа также можно назвать тем же просто <имени свойства первичного ключа> (например, CourseID, так как первичный ключ Course сущности CourseID).Foreign key properties can also be named the same simply <primary key property name> (for example, CourseID since the Course entity's primary key is CourseID).

Сущность CourseThe Course entity

  • В папке Models создайте Course.CS, заменив Код шаблона следующим кодом:In the Models folder, create Course.cs, replacing the template code with the following code:

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace ContosoUniversity.Models
    {
        public class Course
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public int CourseID { get; set; }
            public string Title { get; set; }
            public int Credits { get; set; }
            
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }
    

Свойство Enrollments является свойством навигации.The Enrollments property is a navigation property. Сущность Course может быть связана с любым числом сущностей Enrollment.A Course entity can be related to any number of Enrollment entities.

Дополнительные сведения об атрибуте DatabaseGeneratedAttribute см. в последующем учебнике этой серии.We'll say more about the DatabaseGeneratedAttribute attribute in a later tutorial in this series. Фактически, этот атрибут позволяет ввести первичный ключ для курса, а не использовать базу данных, чтобы создать его.Basically, this attribute lets you enter the primary key for the course rather than having the database generate it.

Создание контекста базы данныхCreate the database context

Класс main, который координирует Entity Framework функциональные возможности для конкретной модели данных, является классом контекста базы данных .The main class that coordinates Entity Framework functionality for a given data model is the database context class. Этот класс создается путем наследования от класса System. Data. Entity. DbContext .You create this class by deriving from the System.Data.Entity.DbContext class. В коде вы указываете, какие сущности включены в модель данных.In your code, you specify which entities are included in the data model. Также вы можете настроить реакцию платформы Entity Framework на некоторые события.You can also customize certain Entity Framework behavior. В этом проекте соответствующий класс называется SchoolContext.In this project, the class is named SchoolContext.

  • Чтобы создать папку в проекте ContosoUniversity, щелкните правой кнопкой мыши проект в Обозреватель решений и нажмите кнопку Добавить, а затем выберите пункт создать папку.To create a folder in the ContosoUniversity project, right-click the project in Solution Explorer and click Add, and then click New Folder. Назовите новую папку DAL (для уровня доступа к данным).Name the new folder DAL (for Data Access Layer). В этой папке создайте новый файл класса с именем SchoolContext.CSи замените код шаблона следующим кодом:In that folder, create a new class file named SchoolContext.cs, and replace the template code with the following code:

    using ContosoUniversity.Models;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    
    namespace ContosoUniversity.DAL
    {
        public class SchoolContext : DbContext
        {
        
            public SchoolContext() : base("SchoolContext")
            {
            }
            
            public DbSet<Student> Students { get; set; }
            public DbSet<Enrollment> Enrollments { get; set; }
            public DbSet<Course> Courses { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
        }
    }
    

Указание наборов сущностейSpecify entity sets

Этот код создает свойство DbSet для каждого набора сущностей.This code creates a DbSet property for each entity set. В терминологии Entity Framework набор сущностей обычно соответствует таблице базы данных, а сущность соответствует строке в таблице.In Entity Framework terminology, an entity set typically corresponds to a database table, and an entity corresponds to a row in the table.

Note

Можно опустить операторы DbSet<Enrollment> и DbSet<Course>, и это будет работать одинаково.You can omit the DbSet<Enrollment> and DbSet<Course> statements and it would work the same. Entity Framework будет включать их неявно, так как сущность Student ссылается на сущность Enrollment, а Enrollment сущность ссылается на сущность Course.Entity Framework would include them implicitly because the Student entity references the Enrollment entity and the Enrollment entity references the Course entity.

Укажите строку подключенияSpecify the connection string

Имя строки подключения (которое будет добавлено в файл Web. config позже) передается в конструктор.The name of the connection string (which you'll add to the Web.config file later) is passed in to the constructor.

public SchoolContext() : base("SchoolContext")
{
}

Можно также передать саму строку подключения, а не имя, которое хранится в файле Web. config.You could also pass in the connection string itself instead of the name of one that is stored in the Web.config file. Дополнительные сведения о параметрах для указания используемой базы данных см. в разделе строки подключения и модели.For more information about options for specifying the database to use, see Connection strings and models.

Если вы не укажете строку соединения или имя явным образом, Entity Framework предполагает, что имя строки подключения совпадает с именем класса.If you don't specify a connection string or the name of one explicitly, Entity Framework assumes that the connection string name is the same as the class name. Имя строки подключения по умолчанию в этом примере будет SchoolContext, то же, что и то, что вы указываете явно.The default connection string name in this example would then be SchoolContext, the same as what you're specifying explicitly.

Укажите имена таблиц в единственном числеSpecify singular table names

Инструкция modelBuilder.Conventions.Remove в методе OnModelCreating предотвращает множественное преобразование имен таблиц.The modelBuilder.Conventions.Remove statement in the OnModelCreating method prevents table names from being pluralized. Если этого не сделать, созданные таблицы в базе данных будут называться Students, Coursesи Enrollments.If you didn't do this, the generated tables in the database would be named Students, Courses, and Enrollments. Вместо этого имена таблиц будут Student, Courseи Enrollment.Instead, the table names will be Student, Course, and Enrollment. В среде разработчиков нет единого мнения о том, следует ли использовать имена таблиц во множественном числе.Developers disagree about whether table names should be pluralized or not. В этом руководстве используется форма единственного числа, но важно отметить, что вы можете выбрать любую из этих форм, включив или опустив эту строку кода.This tutorial uses the singular form, but the important point is that you can select whichever form you prefer by including or omitting this line of code.

Инициализация базы данных с тестовыми даннымиInitialize DB with test data

Entity Framework может автоматически создавать (или удалять и повторно создавать) базу данных при запуске приложения.Entity Framework can automatically create (or drop and re-create) a database for you when the application runs. Можно указать, что это должно выполняться при каждом запуске приложения или только в случае, если модель не синхронизирована с существующей базой данных.You can specify that this should be done every time your application runs or only when the model is out of sync with the existing database. Можно также написать Seed метод, который Entity Framework автоматически вызывается после создания базы данных, чтобы заполнить ее тестовыми данными.You can also write a Seed method that Entity Framework automatically calls after creating the database in order to populate it with test data.

По умолчанию база данных создается только в том случае, если она не существует (и вызывает исключение, если модель изменилась и база данных уже существует).The default behavior is to create a database only if it doesn't exist (and throw an exception if the model has changed and the database already exists). В этом разделе вы укажете, что база данных должна быть удалена и создана повторно при каждом изменении модели.In this section, you'll specify that the database should be dropped and re-created whenever the model changes. Удаление базы данных приводит к утрате всех данных.Dropping the database causes the loss of all your data. Как правило, это нормально во время разработки, поскольку при повторном создании базы данных и повторном создании тестовых данных будет выполняться метод Seed.This is generally okay during development, because the Seed method will run when the database is re-created and will re-create your test data. Но в рабочей среде обычно не требуется терять все данные каждый раз, когда необходимо изменить схему базы данных.But in production you generally don't want to lose all your data every time you need to change the database schema. Далее вы узнаете, как управлять изменениями модели с помощью Code First Migrations для изменения схемы базы данных вместо удаления и повторного создания базы данных.Later you'll see how to handle model changes by using Code First Migrations to change the database schema instead of dropping and re-creating the database.

  1. В папке DAL создайте новый файл класса с именем SchoolInitializer.CS и замените код шаблона следующим кодом, который вызывает создание базы данных при необходимости и загружает тестовые данные в новую базу данных.In the DAL folder, create a new class file named SchoolInitializer.cs and replace the template code with the following code, which causes a database to be created when needed and loads test data into the new database.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;
    using ContosoUniversity.Models;
    
    namespace ContosoUniversity.DAL
    {
        public class SchoolInitializer : System.Data.Entity. DropCreateDatabaseIfModelChanges<SchoolContext>
        {
            protected override void Seed(SchoolContext context)
            {
                var students = new List<Student>
                {
                new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
                new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
                new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
                new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
                new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
                new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
                new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
                new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
                };
    
                students.ForEach(s => context.Students.Add(s));
                context.SaveChanges();
                var courses = new List<Course>
                {
                new Course{CourseID=1050,Title="Chemistry",Credits=3,},
                new Course{CourseID=4022,Title="Microeconomics",Credits=3,},
                new Course{CourseID=4041,Title="Macroeconomics",Credits=3,},
                new Course{CourseID=1045,Title="Calculus",Credits=4,},
                new Course{CourseID=3141,Title="Trigonometry",Credits=4,},
                new Course{CourseID=2021,Title="Composition",Credits=3,},
                new Course{CourseID=2042,Title="Literature",Credits=4,}
                };
                courses.ForEach(s => context.Courses.Add(s));
                context.SaveChanges();
                var enrollments = new List<Enrollment>
                {
                new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
                new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
                new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
                new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
                new Enrollment{StudentID=3,CourseID=1050},
                new Enrollment{StudentID=4,CourseID=1050,},
                new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
                new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
                new Enrollment{StudentID=6,CourseID=1045},
                new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
                };
                enrollments.ForEach(s => context.Enrollments.Add(s));
                context.SaveChanges();
            }
        }
    }
    

    Метод Seed принимает объект контекста базы данных в качестве входного параметра, а код в методе использует этот объект для добавления новых сущностей в базу данных.The Seed method takes the database context object as an input parameter, and the code in the method uses that object to add new entities to the database. Для каждого типа сущности код создает коллекцию новых сущностей, добавляет их в соответствующее свойство DbSet, а затем сохраняет изменения в базе данных.For each entity type, the code creates a collection of new entities, adds them to the appropriate DbSet property, and then saves the changes to the database. Не нужно вызывать метод SaveChanges после каждой группы сущностей, как это сделано здесь, но это помогает узнать источник проблемы, если во время записи кода в базу данных возникает исключение.It isn't necessary to call the SaveChanges method after each group of entities, as is done here, but doing that helps you locate the source of a problem if an exception occurs while the code is writing to the database.

  2. Чтобы указать Entity Framework использовать класс инициализатора, добавьте элемент в элемент entityFramework в файле Web. config приложения (в корневой папке проекта), как показано в следующем примере:To tell Entity Framework to use your initializer class, add an element to the entityFramework element in the application Web.config file (the one in the root project folder), as shown in the following example:

    <entityFramework>
      <contexts>
        <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
          <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
        </context>
      </contexts>
      <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
        <parameters>
          <parameter value="v11.0" />
        </parameters>
      </defaultConnectionFactory>
      <providers>
        <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      </providers>
    </entityFramework>
    

    context type указывает полное имя класса контекста и сборку, в которой он находится, а databaseinitializer type указывает полное имя класса инициализатора и сборку, в которой он находится.The context type specifies the fully qualified context class name and the assembly it's in, and the databaseinitializer type specifies the fully qualified name of the initializer class and the assembly it's in. (Если не нужно, чтобы EF использовал инициализатор, можно задать атрибут для элемента context: disableDatabaseInitialization="true".) Дополнительные сведения см. в разделе Параметры файла конфигурации.(When you don't want EF to use the initializer, you can set an attribute on the context element: disableDatabaseInitialization="true".) For more information, see Configuration File Settings.

    Альтернативой заданию инициализатора в файле Web. config является это сделать в коде, добавив оператор Database.SetInitializer в метод Application_Start в файле Global.asax.CS .An alternative to setting the initializer in the Web.config file is to do it in code by adding a Database.SetInitializer statement to the Application_Start method in the Global.asax.cs file. Дополнительные сведения см. в разделе Основные сведения об инициализаторах баз данных в Entity Framework Code First.For more information, see Understanding Database Initializers in Entity Framework Code First.

Теперь приложение настроено таким образом, что при первом обращении к базе данных в заданном запуске приложения Entity Framework сравнивает базу данных с моделью (ваша SchoolContext и классы сущностей).The application is now set up so that when you access the database for the first time in a given run of the application, Entity Framework compares the database to the model (your SchoolContext and entity classes). При наличии разницы приложение удаляет и повторно создает базу данных.If there's a difference, the application drops and re-creates the database.

Note

При развертывании приложения на рабочем веб-сервере необходимо удалить или отключить код, который удаляет и повторно создает базу данных.When you deploy an application to a production web server, you must remove or disable code that drops and re-creates the database. Это можно сделать в последующем учебнике этой серии.You'll do that in a later tutorial in this series.

Настройка EF 6 для использования LocalDBSet up EF 6 to use LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express.LocalDB is a lightweight version of the SQL Server Express database engine. Его легко установить и настроить, запустить по запросу и запустить в пользовательском режиме.It's easy to install and configure, starts on demand, and runs in user mode. LocalDB выполняется в специальном режиме выполнения SQL Server Express, который позволяет работать с базами данных в виде MDF -файлов.LocalDB runs in a special execution mode of SQL Server Express that enables you to work with databases as .mdf files. Файлы базы данных LocalDB можно поместить в папку данных приложения_ веб-проекта, если требуется скопировать базу данных вместе с проектом.You can put LocalDB database files in the App_Data folder of a web project if you want to be able to copy the database with the project. Функция пользовательского экземпляра в SQL Server Express также позволяет работать с MDF -файлами, но функция пользовательского экземпляра является устаревшей. Поэтому для работы с MDF -файлами рекомендуется использовать LocalDB.The user instance feature in SQL Server Express also enables you to work with .mdf files, but the user instance feature is deprecated; therefore, LocalDB is recommended for working with .mdf files. LocalDB устанавливается по умолчанию в Visual Studio.LocalDB is installed by default with Visual Studio.

Как правило, SQL Server Express не используется для рабочих веб-приложений.Typically, SQL Server Express is not used for production web applications. LocalDB в частности не рекомендуется для использования в рабочей среде с веб-приложением, поскольку оно не предназначено для работы с IIS.LocalDB in particular is not recommended for production use with a web application because it's not designed to work with IIS.

  • В этом руководстве вы будете работать с LocalDB.In this tutorial, you'll work with LocalDB. Откройте файл Web. config приложения и добавьте элемент connectionStrings перед элементом appSettings, как показано в следующем примере.Open the application Web.config file and add a connectionStrings element preceding the appSettings element, as shown in the following example. (Убедитесь, что вы обновляете файл Web. config в корневой папке проекта.(Make sure you update the Web.config file in the root project folder. Существует также файл Web. config в подпапке views , которую не нужно обновлять.)There's also a Web.config file in the Views subfolder that you don't need to update.)

    <connectionStrings>
        <add name="SchoolContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" 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>
    

Добавленная строка подключения указывает, что Entity Framework будет использовать базу данных LocalDB с именем ContosoUniversity1. mdf.The connection string you've added specifies that Entity Framework will use a LocalDB database named ContosoUniversity1.mdf. (База данных пока не существует, но EF создаст ее.) Если вы хотите создать базу данных в папке приложения_данных , можно добавить AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf в строку подключения.(The database doesn't exist yet but EF will create it.) If you want to create the database in your App_Data folder, you could add AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf to the connection string. Дополнительные сведения о строках подключения см. в разделе SQL Server строки подключения для веб-приложений ASP.NET.For more information about connection strings, see SQL Server Connection Strings for ASP.NET Web Applications.

В файле Web. config действительно не требуется строка подключения.You don't actually need a connection string in the Web.config file. Если строка подключения не указана, Entity Framework использует строку подключения по умолчанию на основе класса контекста.If you don't supply a connection string, Entity Framework uses a default connection string based on your context class. Дополнительные сведения см. в разделе Code First к новой базе данных.For more information, see Code First to a New Database.

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

Теперь вы создадите веб-страницу для вывода данных.Now you'll create a web page to display data. Процесс запроса данных автоматически инициирует создание базы данных.The process of requesting the data automatically triggers the creation of the database. Начнем с создания нового контроллера.You'll begin by creating a new controller. Но прежде чем это сделать, постройте проект, чтобы сделать классы модели и контекста доступными для формирования шаблонов контроллера MVC.But before you do that, build the project to make the model and context classes available to MVC controller scaffolding.

  1. Щелкните правой кнопкой мыши папку Controllers в Обозреватель решений, выберите добавить, а затем — новый шаблонный элемент.Right-click the Controllers folder in Solution Explorer, select Add, and then click New Scaffolded Item.

  2. В диалоговом окне Добавление шаблона выберите контроллер MVC 5 с представлениями с помощью Entity Frameworkи нажмите кнопку добавить.In the Add Scaffold dialog box, select MVC 5 Controller with views, using Entity Framework, and then choose Add.

    Диалоговое окно "Добавление шаблона" в Visual Studio

  3. В диалоговом окне Добавление контроллера выберите следующие параметры, а затем нажмите кнопку Добавить.In the Add Controller dialog box, make the following selections, and then choose Add:

    • Класс модели: Student (ContosoUniversity. Models) .Model class: Student (ContosoUniversity.Models). (Если этот параметр не отображается в раскрывающемся списке, выполните сборку проекта и повторите попытку.)(If you don't see this option in the drop-down list, build the project and try again.)

    • Класс контекста данных: SchoolContext (ContosoUniversity. DAL) .Data context class: SchoolContext (ContosoUniversity.DAL).

    • Имя контроллера: студентконтроллер (не StudentsController).Controller name: StudentController (not StudentsController).

    • Оставьте значения по умолчанию для других полей.Leave the default values for the other fields.

      При нажатии кнопки Добавитьсоздается файл StudentController.CS и набор представлений (CSHTML -файлов), которые работают с контроллером.When you click Add, the scaffolder creates a StudentController.cs file and a set of views (.cshtml files) that work with the controller. В будущем при создании проектов, использующих Entity Framework, можно также воспользоваться некоторыми дополнительными функциональными возможностями средства формирования шаблонов: создать первый класс модели, не создавать строку подключения, а затем в поле Добавить контроллер укажите новый контекст данных , нажав кнопку + рядом с классом контекста данных.In the future when you create projects that use Entity Framework, you can also take advantage of some additional functionality of the scaffolder: create your first model class, don't create a connection string, and then in the Add Controller box specify New data context by selecting the + button next to Data context class. Формирование шаблонов создаст класс DbContext и строку подключения, а также контроллер и представления.The scaffolder will create your DbContext class and your connection string as well as the controller and views.

  4. Visual Studio откроет файл контроллерс\студентконтроллер.КС .Visual Studio opens the Controllers\StudentController.cs file. Вы видите, что создана переменная класса, которая создает экземпляр объекта контекста базы данных:You see that a class variable has been created that instantiates a database context object:

    private SchoolContext db = new SchoolContext();
    

    Метод действия Index возвращает список учащихся из набора сущностей Student , считывая свойство Students экземпляра контекста базы данных:The Index action method gets a list of students from the Students entity set by reading the Students property of the database context instance:

    public ViewResult Index()
    {
        return View(db.Students.ToList());
    }
    

    В представлении студент\индекс.кштмл этот список отображается в таблице:The Student\Index.cshtml view displays this list in a table:

    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.LastName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstMidName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </th>
            <th></th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ID })
            </td>
        </tr>
    }
    
  5. Чтобы запустить проект, нажмите сочетание клавиш CTRL+F5.Press Ctrl+F5 to run the project. (Если вы получаете ошибку "не удается создать теневую копию", закройте браузер и повторите попытку.)(If you get a "Cannot create Shadow Copy" error, close the browser and try again.)

    Щелкните вкладку students (учащиеся ), чтобы просмотреть тестовые данные, вставленные методом Seed.Click the Students tab to see the test data that the Seed method inserted. В зависимости от того, насколько ограничивается окно браузера, вы увидите ссылку на вкладку Student в верхней адресной строке или щелкните правый верхний угол, чтобы увидеть ссылку.Depending on how narrow your browser window is, you'll see the Student tab link in the top address bar or you'll have to click the upper right corner to see the link.

    Кнопка меню

Просмотр базы данныхView the database

Когда вы запустили страницу учащихся и приложение попыталось получить доступ к базе данных, EF обнаружил, что база данных не была создана и не создала ее.When you ran the Students page and the application tried to access the database, EF discovered that there was no database and created one. Затем EF запустил метод SEED для заполнения базы данных данными.EF then ran the seed method to populate the database with data.

Для просмотра базы данных в Visual Studio можно использовать либо Обозреватель сервера , либо Обозреватель объектов SQL Server (SSOX).You can use either Server Explorer or SQL Server Object Explorer (SSOX) to view the database in Visual Studio. В этом руководстве вы будете использовать Обозреватель сервера.For this tutorial, you'll use Server Explorer.

  1. Закройте браузер.Close the browser.

  2. В Обозреватель серверараскройте узел подключения к данным (сначала необходимо нажать кнопку Обновить), раскройте узел School context (ContosoUniversity) , а затем разверните узел таблицы , чтобы просмотреть таблицы в новой базе данных.In Server Explorer, expand Data Connections (you may need to select the refresh button first), expand School Context (ContosoUniversity), and then expand Tables to see the tables in your new database.

  3. Щелкните правой кнопкой мыши таблицу Student и выберите команду Показать данные таблицы , чтобы просмотреть созданные столбцы и строки, вставленные в таблицу.Right-click the Student table and click Show Table Data to see the columns that were created and the rows that were inserted into the table.

  4. Закройте подключение Обозреватель сервера .Close the Server Explorer connection.

Файлы базы данных ContosoUniversity1. mdf и . ldf находятся в папке % UserProfile% .The ContosoUniversity1.mdf and .ldf database files are in the %USERPROFILE% folder.

Поскольку вы используете DropCreateDatabaseIfModelChanges инициализатор, теперь можно внести изменения в класс Student, запустить приложение еще раз, и база данных будет автоматически создана заново в соответствии с внесенным изменением.Because you're using the DropCreateDatabaseIfModelChanges initializer, you could now make a change to the Student class, run the application again, and the database would automatically be re-created to match your change. Например, если добавить в класс Student EmailAddress свойство, снова запустить страницу Students и снова просмотреть таблицу, появится новый столбец EmailAddress.For example, if you add an EmailAddress property to the Student class, run the Students page again, and then look at the table again, you'll see a new EmailAddress column.

СоглашенияConventions

Объем кода, который вам пришлось писать, чтобы Entity Framework иметь возможность создать полную базу данных для вас, является минимальным из-за соглашенийили допущений, которые Entity Framework делают.The amount of code you had to write in order for Entity Framework to be able to create a complete database for you is minimal because of conventions, or assumptions that Entity Framework makes. Некоторые из них уже были отмечены или использованы без вашего уведомления:Some of them have already been noted or were used without your being aware of them:

  • В качестве имен таблиц используются множественные формы имен классов сущностей.The pluralized forms of entity class names are used as table names.
  • В качестве имен столбцов используются имена свойств сущностей.Entity property names are used for column names.
  • Свойства сущности с именами ID или classname ID распознаются как свойства первичного ключа.Entity properties that are named ID or classname ID are recognized as primary key properties.
  • Свойство интерпретируется как свойство внешнего ключа, если оно называется <имя свойства навигации><имя свойства первичного ключа> (например, StudentID для свойства навигации Student, так как первичный ключ Student сущности ID).A property is interpreted as a foreign key property if it's named <navigation property name><primary key property name> (for example, StudentID for the Student navigation property since the Student entity's primary key is ID). Свойства внешнего ключа также можно назвать тем же просто <имени свойства первичного ключа> (например, EnrollmentID, так как первичный ключ Enrollment сущности EnrollmentID).Foreign key properties can also be named the same simply <primary key property name> (for example, EnrollmentID since the Enrollment entity's primary key is EnrollmentID).

Вы видели, что соглашения можно переопределить.You've seen that conventions can be overridden. Например, вы указали, что имена таблиц не должны быть в множественном числе, и позже вы увидите, как явно пометить свойство как свойство внешнего ключа.For example, you specified that table names shouldn't be pluralized, and you'll see later how to explicitly mark a property as a foreign key property.

Получение кодаGet the code

Скачать завершенный проектDownload Completed Project

Дополнительные ресурсыAdditional resources

Дополнительные сведения об EF 6 см. в следующих статьях:For more about EF 6, see these articles:

Дальнейшие действияNext steps

Изучив это руководство, вы:In this tutorial, you:

  • Создано веб-приложение MVCCreated an MVC web app
  • Настройка стиля сайтаSet up the site style
  • Установлено Entity Framework 6Installed Entity Framework 6
  • Создание модели данныхCreated the data model
  • Создание контекста базы данныхCreated the database context
  • Инициализация базы данных с тестовыми даннымиInitialized DB with test data
  • Настройка EF 6 для использования LocalDBSet up EF 6 to use LocalDB
  • Создание контроллера и представленийCreated controller and views
  • Просмотр базы данныхViewed the database

Перейдите к следующей статье, чтобы узнать, как просмотреть и настроить код создания, чтения, обновления и удаления (CRUD) в контроллерах и представлениях.Advance to the next article to learn how to review and customize the create, read, update, delete (CRUD) code in your controllers and views.