Руководство. Использование миграций EF в приложении MVC ASP.NET и развертывание в Azure

До сих пор пример веб-приложения Университета Contoso выполняется локально в IIS Express на компьютере разработчика. Чтобы сделать реальное приложение доступным для использования другими пользователями через Интернет, необходимо развернуть его в поставщике услуг веб-хостинга. В этом руководстве описано, как включить миграцию Code First и развернуть приложение в облаке в Azure:

  • Включите Code First Migrations. Функция миграции позволяет изменить модель данных и развернуть изменения в рабочей среде, обновив схему базы данных без необходимости удалять и повторно создавать базу данных.
  • Разверните его в Azure. Этот шаг является необязательным; Вы можете продолжить работу с оставшимися руководствами, не развертывая проект.

Мы рекомендуем использовать процесс непрерывной интеграции с системой управления версиями для развертывания, но в этом руководстве эти темы не рассматриваются. Дополнительные сведения см. в разделах о системе управления версиями и непрерывной интеграциистатьи Создание облачных приложений Real-World с помощью Azure.

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

  • Включение миграции Code First
  • Развертывание приложения в Azure (необязательно)

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

Включение миграции Code First

При разработке нового приложения ваша модель данных часто меняется, и при каждом таком изменении она нарушает синхронизацию с базой данных. Вы настроили Entity Framework для автоматического удаления и повторного создания базы данных при каждом изменении модели данных. При добавлении, удалении или изменении классов сущностей или изменении DbContext класса при следующем запуске приложения оно автоматически удаляет существующую базу данных, создает новую, соответствующую модели, и заполняет ее тестовые данные.

Этот способ для обеспечения синхронизации базы данных с моделью данных хорошо работает до развертывания приложения в рабочей среде. Когда приложение выполняется в рабочей среде, оно обычно хранит данные, которые вы хотите сохранить, и вы не хотите терять все при каждом внесении изменений, таких как добавление нового столбца. Функция Code First Migrations решает эту проблему, позволяя Code First обновить схему базы данных вместо удаления и повторного создания базы данных. В этом руководстве вы развернете приложение, а для подготовки к этому включите миграции.

  1. Отключите инициализатор, настроенный ранее, закомментируйте или удалив contexts элемент, добавленный в файл Web.config приложения.

    <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>
    
  2. Кроме того, в файле Web.config приложения измените имя базы данных в строке подключения на ContosoUniversity2.

    <connectionStrings>
      <add name="SchoolContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=ContosoUniversity2;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
    </connectionStrings>
    

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

  3. В меню Инструменты выберите Диспетчер пакетов NuGet>Консоль диспетчера пакетов.

  4. В командной строке PM> введите следующие команды:

    enable-migrations
    add-migration InitialCreate
    

    Команда enable-migrations создает папку Migrations в проекте ContosoUniversity и помещает в нее файл Configuration.cs , который можно изменить для настройки миграций.

    (Если вы пропустили описанный выше шаг, указывающий на изменение имени базы данных, служба миграции найдет существующую базу данных и автоматически выполнит add-migration команду. Это нормально, это просто означает, что вы не будете выполнять тест кода миграции перед развертыванием базы данных. Позже при выполнении update-database команды ничего не произойдет, так как база данных уже существует.)

    Откройте файл ContosoUniversity\Migrations\Configuration.cs . Как и класс инициализатора, который вы видели ранее, класс Configuration включает Seed метод .

    internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }
    
        protected override void Seed(ContosoUniversity.DAL.SchoolContext context)
        {
            //  This method will be called after migrating to the latest version.
    
            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
    }
    

    Метод Seed предназначен для вставки или обновления тестовых данных после создания или обновления базы данных Code First. Метод вызывается при создании базы данных и при каждом обновлении схемы базы данных после изменения модели данных.

Настройка метода Seed

При удалении и повторном создании базы данных для каждого изменения модели данных используется метод класса инициализатора Seed для вставки тестовых данных, так как после каждого изменения модели база данных удаляется и все тестовые данные теряются. При использовании Code First Migrations тестовые данные сохраняются после изменений базы данных, поэтому включать тестовые данные в метод Seed обычно не требуется. На самом деле, вы не хотите Seed , чтобы метод вставлял тестовые данные, если вы будете использовать миграции для развертывания базы данных в рабочей среде, так как Seed метод будет выполняться в рабочей среде. В этом случае требуется Seed , чтобы метод вставлял в базу данных только данные, необходимые в рабочей среде. Например, может потребоваться, чтобы база данных включала в таблицу Department фактические имена отделов, когда приложение станет доступным в рабочей среде.

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

  1. Замените содержимое файла Configuration.cs следующим кодом, который загружает тестовые данные в новую базу данных.

    namespace ContosoUniversity.Migrations
    {
        using ContosoUniversity.Models;
        using System;
        using System.Collections.Generic;
        using System.Data.Entity;
        using System.Data.Entity.Migrations;
        using System.Linq;
    
        internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext>
        {
            public Configuration()
            {
                AutomaticMigrationsEnabled = false;
            }
    
            protected override void Seed(ContosoUniversity.DAL.SchoolContext context)
            {
                var students = new List<Student>
                {
                    new Student { FirstMidName = "Carson",   LastName = "Alexander", 
                        EnrollmentDate = DateTime.Parse("2010-09-01") },
                    new Student { FirstMidName = "Meredith", LastName = "Alonso",    
                        EnrollmentDate = DateTime.Parse("2012-09-01") },
                    new Student { FirstMidName = "Arturo",   LastName = "Anand",     
                        EnrollmentDate = DateTime.Parse("2013-09-01") },
                    new Student { FirstMidName = "Gytis",    LastName = "Barzdukas", 
                        EnrollmentDate = DateTime.Parse("2012-09-01") },
                    new Student { FirstMidName = "Yan",      LastName = "Li",        
                        EnrollmentDate = DateTime.Parse("2012-09-01") },
                    new Student { FirstMidName = "Peggy",    LastName = "Justice",   
                        EnrollmentDate = DateTime.Parse("2011-09-01") },
                    new Student { FirstMidName = "Laura",    LastName = "Norman",    
                        EnrollmentDate = DateTime.Parse("2013-09-01") },
                    new Student { FirstMidName = "Nino",     LastName = "Olivetto",  
                        EnrollmentDate = DateTime.Parse("2005-08-11") }
                };
                students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, 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.AddOrUpdate(p => p.Title, s));
                context.SaveChanges();
    
                var enrollments = new List<Enrollment>
                {
                    new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Alexander").ID, 
                        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
                        Grade = Grade.A 
                    },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Alexander").ID,
                        CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, 
                        Grade = Grade.C 
                     },                            
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Alexander").ID,
                        CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, 
                        Grade = Grade.B
                     },
                     new Enrollment { 
                         StudentID = students.Single(s => s.LastName == "Alonso").ID,
                        CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, 
                        Grade = Grade.B 
                     },
                     new Enrollment { 
                         StudentID = students.Single(s => s.LastName == "Alonso").ID,
                        CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, 
                        Grade = Grade.B 
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alonso").ID,
                        CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, 
                        Grade = Grade.B 
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Anand").ID,
                        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Anand").ID,
                        CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                        Grade = Grade.B         
                     },
                    new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Barzdukas").ID,
                        CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                        Grade = Grade.B         
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Li").ID,
                        CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                        Grade = Grade.B         
                     },
                     new Enrollment { 
                        StudentID = students.Single(s => s.LastName == "Justice").ID,
                        CourseID = courses.Single(c => c.Title == "Literature").CourseID,
                        Grade = Grade.B         
                     }
                };
    
                foreach (Enrollment e in enrollments)
                {
                    var enrollmentInDataBase = context.Enrollments.Where(
                        s =>
                             s.Student.ID == e.StudentID &&
                             s.Course.CourseID == e.CourseID).SingleOrDefault();
                    if (enrollmentInDataBase == null)
                    {
                        context.Enrollments.Add(e);
                    }
                }
                context.SaveChanges();
            }
        }
    }
    

    Метод Seed принимает объект контекста базы данных в качестве входного параметра, а код в методе использует этот объект для добавления новых сущностей в базу данных. Для каждого типа сущности код создает коллекцию новых сущностей, добавляет их в соответствующее свойство DbSet , а затем сохраняет изменения в базе данных. Не нужно вызывать метод SaveChanges после каждой группы сущностей, как показано здесь, но это поможет найти источник проблемы при возникновении исключения во время записи кода в базу данных.

    Некоторые операторы, которые вставляют данные, используют метод AddOrUpdate для выполнения операции upsert. Seed Так как метод выполняется каждый раз при выполнении update-database команды, обычно после каждой миграции невозможно просто вставить данные, так как строки, которые вы пытаетесь добавить, уже будут там после первой миграции, создающей базу данных. Операция upsert предотвращает ошибки, которые могут возникнуть при попытке вставить уже существующую строку, но переопределяет любые изменения данных, которые могли быть внесены во время тестирования приложения. Если тестовые данные находятся в некоторых таблицах, это может не произойти. В некоторых случаях при изменении данных во время тестирования требуется, чтобы изменения сохранялись после обновления базы данных. В этом случае требуется выполнить условную операцию вставки: вставить строку, только если она еще не существует. Метод Seed использует оба подхода.

    Первый параметр, передаваемый методу AddOrUpdate, указывает свойство для проверка, если строка уже существует. Для данных тестового учащегося, которые вы предоставляете, свойство можно использовать для этой цели, LastName так как каждая фамилия в списке уникальна:

    context.Students.AddOrUpdate(p => p.LastName, s)
    

    В этом коде предполагается, что фамилии уникальны. При добавлении учащегося с повторяющимся именем вы получите следующее исключение при следующем выполнении миграции:

    Последовательность содержит несколько элементов

    Сведения об обработке избыточных данных, таких как два учащегося с именем "Александр Карсон" , см. в блоге Рика Андерсона. Дополнительные сведения о методе см. в AddOrUpdate статье Использование метода AddOrUpdate для EF 4.3 в блоге Джули Лерман.

    В коде, который создает Enrollment сущности, предполагается, что у вас есть ID значение в сущностях в students коллекции, хотя это свойство не задано в коде, который создает коллекцию.

    new Enrollment { 
        StudentID = students.Single(s => s.LastName == "Alexander").ID, 
        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
        Grade = Grade.A 
    },
    

    Здесь можно использовать ID свойство , так как ID значение задается при вызове SaveChangesstudents для коллекции. EF автоматически получает значение первичного ключа при вставке сущности в базу данных и обновляет ID свойство сущности в памяти.

    Код, добавляющий каждую Enrollment сущность в Enrollments набор сущностей, не использует AddOrUpdate метод . Он проверяет, существует ли сущность, и вставляет сущность, если она не существует. Этот подход сохраняет изменения, внесенные в оценку регистрации с помощью пользовательского интерфейса приложения. Код циклически выполняется по каждому члену Enrollmentсписка , и если регистрация не найдена в базе данных, он добавляет регистрацию в базу данных. При первом обновлении базы данных она будет пустой, поэтому она будет добавлять каждую регистрацию.

    foreach (Enrollment e in enrollments)
    {
        var enrollmentInDataBase = context.Enrollments.Where(
            s => s.Student.ID == e.Student.ID &&
                 s.Course.CourseID == e.Course.CourseID).SingleOrDefault();
        if (enrollmentInDataBase == null)
        {
            context.Enrollments.Add(e);
        }
    }
    
  2. Выполните построение проекта.

Выполнение первой миграции

При выполнении add-migration команды Migrations сгенерировал код, который создаст базу данных с нуля. Этот код также находится в папке Migrations в файле с именем <timestamp>_InitialCreate.cs. Метод UpInitialCreate класса создает таблицы базы данных, соответствующие наборам сущностей модели данных, и Down метод удаляет их.

public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Course",
            c => new
                {
                    CourseID = c.Int(nullable: false),
                    Title = c.String(),
                    Credits = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.CourseID);
        
        CreateTable(
            "dbo.Enrollment",
            c => new
                {
                    EnrollmentID = c.Int(nullable: false, identity: true),
                    CourseID = c.Int(nullable: false),
                    StudentID = c.Int(nullable: false),
                    Grade = c.Int(),
                })
            .PrimaryKey(t => t.EnrollmentID)
            .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true)
            .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true)
            .Index(t => t.CourseID)
            .Index(t => t.StudentID);
        
        CreateTable(
            "dbo.Student",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    LastName = c.String(),
                    FirstMidName = c.String(),
                    EnrollmentDate = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.ID);
        
    }
    
    public override void Down()
    {
        DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student");
        DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course");
        DropIndex("dbo.Enrollment", new[] { "StudentID" });
        DropIndex("dbo.Enrollment", new[] { "CourseID" });
        DropTable("dbo.Student");
        DropTable("dbo.Enrollment");
        DropTable("dbo.Course");
    }
}

Функция миграций вызывает метод Up, чтобы реализовать изменения модели данных для миграции. При вводе команды для отката обновления функция миграций вызывает метод Down.

Это начальная миграция, созданная при вводе add-migration InitialCreate команды. Параметр (InitialCreate в примере) используется для имени файла и может быть любым. Обычно вы выбираете слово или фразу, которые суммируют действия, выполняемые в миграции. Например, последнюю миграцию можно назвать "AddDepartmentTable".

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

  1. В окне Консоль диспетчера пакетов введите следующую команду:

    update-database

    Команда update-database запускает Up метод для создания базы данных, а затем запускает Seed метод для заполнения базы данных. Этот же процесс будет выполняться автоматически в рабочей среде после развертывания приложения, как показано в следующем разделе.

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

Развернуть в Azure

До сих пор приложение выполнялось локально в IIS Express на компьютере разработки. Чтобы сделать его доступным для других пользователей через Интернет, необходимо развернуть его у поставщика услуг веб-хостинга. В этом разделе руководства вы развернете его в Azure. Этот раздел является необязательным; Вы можете пропустить это и продолжить работу со следующим руководством или адаптировать инструкции в этом разделе для другого поставщика услуг размещения по своему выбору.

Использование миграции Code First для развертывания базы данных

Чтобы развернуть базу данных, используйте Code First Migrations. При создании профиля публикации, который используется для настройки параметров развертывания из Visual Studio, вы выберете проверка поле с меткой Обновить базу данных. Этот параметр заставляет процесс развертывания автоматически настроить файл Web.config приложения на целевом сервере, чтобы Code First использовал класс инициализатора MigrateDatabaseToLatestVersion .

Visual Studio не выполняет никаких действий с базой данных во время развертывания во время копирования проекта на целевой сервер. Когда вы запускаете развернутое приложение и оно обращается к базе данных в первый раз после развертывания, Code First проверяет, соответствует ли база данных модели данных. В случае несоответствия Code First автоматически создает базу данных (если она еще не существует) или обновляет схему базы данных до последней версии (если база данных существует, но не соответствует модели). Если приложение реализует метод Migrations Seed , метод запускается после создания базы данных или обновления схемы.

Метод Migrations Seed вставляет тестовые данные. При развертывании в рабочей среде необходимо изменить Seed метод таким образом, чтобы он вставлял только данные, которые нужно вставить в рабочую базу данных. Например, в текущей модели данных может потребоваться, чтобы в базе данных разработчиков были реальные курсы, но вымышленные учащиеся. Вы можете написать Seed метод для загрузки в разработку, а затем закомментировать вымышленных учащихся перед развертыванием в рабочей среде. Вы также можете написать метод для загрузки только курсов и ввести вымышленных учащихся в тестовую Seed базу данных вручную с помощью пользовательского интерфейса приложения.

Получение учетной записи Azure

Вам потребуется учетная запись Azure. Если у вас еще нет подписки, но у вас есть подписка Visual Studio, вы можете активировать преимущества подписки. В противном случае вы можете создать бесплатную пробную учетную запись всего за несколько минут. Дополнительные сведения см. в разделе Бесплатная пробная версия Azure.

Создание веб-сайта и базы данных SQL в Azure

Веб-приложение в Azure будет выполняться в общей среде размещения, то есть оно выполняется на виртуальных машинах, которые совместно используются для других клиентов Azure. Общая среда внешнего размещения – это недорогой способ начать работу в облачной среде. Если позднее ваш веб-трафик увеличится, приложение можно масштабировать по необходимости, запуская его на выделенных виртуальных машинах. Дополнительные сведения о вариантах ценообразования для Служба приложений Azure см. в Служба приложений ценах.

Вы развернете базу данных в Azure SQL базе данных. База данных SQL — это облачная служба реляционных баз данных, созданная на основе SQL Server технологий. Средства и приложения, работающие с SQL Server также работать с базой данных SQL.

  1. На портале управления Azure выберите Создать ресурс на вкладке слева, а затем щелкните Просмотреть все в области Создание (или колонке), чтобы просмотреть все доступные ресурсы. Выберите Веб-приложение + SQL в разделе Веб колонки Все . Наконец, нажмите кнопку Создать.

    Создание ресурса в портал Azure

    Откроется форма для создания нового ресурса веб-приложения и SQL .

  2. Введите строку в поле Имя приложения , которая будет использоваться в качестве уникального URL-адреса приложения. Полный URL-адрес будет состоять из того, что вы вводите здесь, а также домена по умолчанию служб приложение Azure (.azurewebsites.net). Если имя приложения уже выбрано, мастер уведомит вас красным сообщением Имя приложения недоступно . Если имя приложения доступно, вы увидите зеленую галочку.

  3. В поле Подписка выберите подписку Azure, в которой должен находиться Служба приложений.

  4. В текстовом поле Группа ресурсов выберите группу ресурсов или создайте новую. Этот параметр указывает, в каком центре обработки данных будет работать веб-сайт. Дополнительные сведения о группах ресурсов см. в разделе Группы ресурсов.

  5. Создайте план Служба приложений, щелкнув раздел Служба приложенийСоздать и заполните Служба приложений план (может быть таким же именем, как Служба приложений), Расположение и Ценовая категория (доступен бесплатный вариант).

  6. Щелкните База данных SQL, а затем выберите Создать новую базу данных или выберите существующую.

  7. В поле Имя введите имя базы данных.

  8. Щелкните поле Целевой сервер и выберите Создать новый сервер. Кроме того, если вы ранее создали сервер, его можно выбрать из списка доступных серверов.

  9. Выберите раздел Ценовая категория , а затем — Бесплатный. Если требуются дополнительные ресурсы, базу данных можно масштабировать в любое время. Дополнительные сведения о ценах на Azure SQL см. в разделе Цены на базу данных Azure SQL.

  10. При необходимости измените параметры сортировки .

  11. Введите имя администратора SQL Администратор имя пользователя и пароль sql Администратор.

    • Если вы выбрали Новый сервер База данных SQL, определите новое имя и пароль, которые будут использоваться позже при доступе к базе данных.
    • Если вы выбрали ранее созданный сервер, введите учетные данные для этого сервера.
  12. Сбор данных телеметрии можно включить для Служба приложений с помощью Application Insights. При небольшой конфигурации Application Insights собирает ценные сведения о событиях, исключениях, зависимостях, запросах и трассировках. Дополнительные сведения о Application Insights см. в статье Azure Monitor.

  13. Нажмите кнопку Создать внизу, чтобы указать, что все готово.

    Портал управления возвращается на страницу Панель мониторинга, а область Уведомления в верхней части страницы показывает, что сайт создается. Через некоторое время (обычно менее минуты) появляется уведомление о том, что развертывание выполнено успешно. На панели навигации слева в разделе Службы приложений появится новое Служба приложений, а новая база данных SQL — в разделе Базы данных SQL.

Развертывание приложения в Azure

  1. В Visual Studio щелкните правой кнопкой мыши проект в обозревателе решений и выберите Опубликовать в контекстном меню.

  2. На странице Выбор целевого объекта публикации выберите Служба приложений, а затем Выберите существующий, а затем нажмите кнопку Опубликовать.

    Выбор целевой страницы публикации

  3. Если вы ранее не добавляли подписку Azure в Visual Studio, выполните действия на экране. Эти действия позволяют Visual Studio подключиться к подписке Azure, чтобы список Служб приложений включал ваш веб-сайт.

  4. На странице Служба приложений выберите подписку, в Служба приложений. В разделе Представление выберите Группа ресурсов. Разверните группу ресурсов, в который вы добавили Служба приложений, и выберите Служба приложений. Нажмите кнопку ОК , чтобы опубликовать приложение.

  5. В окне Вывод указывается, какие действия по развертыванию были выполнены, а также сообщается об успешном завершении развертывания.

  6. После успешного развертывания браузер по умолчанию автоматически открывает URL-адрес развернутого веб-сайта.

    Students_index_page_with_paging

    Теперь приложение работает в облаке.

На этом этапе база данных SchoolContext была создана в базе данных Azure SQL, так как вы выбрали выполнить Code First Migrations (выполняется при запуске приложения). Файл Web.config на развернутом веб-сайте был изменен таким образом, что инициализатор MigrateDatabaseToLatestVersion запускается при первом чтении или записи данных в базе данных (что произошло при выборе вкладки Учащиеся ):

 фрагмент файлаWeb.config

В процессе развертывания также была создана новая строка подключения (SchoolContext_DatabasePublish), которую Code First Migrations использовать для обновления схемы базы данных и заполнения базы данных.

Строка подключения в файле Web.config

Развернутую версию файла Web.config можно найти на своем компьютере в ContosoUniversity\obj\Release\Package\PackageTmp\Web.config. Вы можете получить доступ к самому развернутой Web.config файлу с помощью FTP. Инструкции см . в разделе ASP.NET веб-развертывание с помощью Visual Studio: развертывание обновления кода. Следуйте инструкциям, которые начинаются с "Чтобы использовать средство FTP, вам потребуется три вещи: URL-адрес FTP, имя пользователя и пароль".

Примечание

Веб-приложение не реализует безопасность, поэтому любой, кто находит URL-адрес, может изменить данные. Инструкции по защите веб-сайта см. в статье Развертывание безопасного приложения MVC ASP.NET с использованием членства, OAuth и базы данных SQL в Azure. Вы можете запретить другим пользователям использовать сайт, остановив службу с помощью портала управления Azure или серверной Обозреватель в Visual Studio.

Пункт меню

Сценарии расширенной миграции

Если вы развертываете базу данных, автоматически выполняя миграции, как показано в этом руководстве, и выполняете развертывание на веб-сайте, работающем на нескольких серверах, вы можете получить несколько серверов, пытающихся выполнить миграцию одновременно. Миграции являются атомарными, поэтому если два сервера попытаются выполнить одну и ту же миграцию, один из них завершится успешно, а другой завершится ошибкой (при условии, что операции невозможно выполнить дважды). В этом сценарии, если вы хотите избежать этих проблем, вы можете вызвать миграцию вручную и настроить собственный код, чтобы это произошло только один раз. Дополнительные сведения см. в статье Выполнение и создание скриптов миграции из кода в блоге и Migrate.exe Rowan Miller (для выполнения миграций из командной строки).

Сведения о других сценариях миграции см. в разделе Миграции Серии экранных трансляций.

Обновление конкретной миграции

update-database -target MigrationName

Команда update-database -target MigrationName выполняет целевую миграцию.

Игнорировать изменения миграции в базе данных

Add-migration MigrationName -ignoreChanges

ignoreChangesсоздает пустую миграцию с текущей моделью в качестве snapshot.

Инициализаторы Code First

В разделе развертывания вы видели, как используется инициализатор MigrateDatabaseToLatestVersion . Code First также предоставляет другие инициализаторы, включая CreateDatabaseIfNotExists (по умолчанию), DropCreateDatabaseIfModelChanges (который использовался ранее) и DropCreateDatabaseAlways. Инициализатор DropCreateAlways может быть полезен для настройки условий для модульных тестов. Вы также можете написать собственные инициализаторы и вызвать инициализатор явным образом, если не хотите ждать, пока приложение считывает данные из базы данных или записывает их в базу данных.

Дополнительные сведения об инициализаторах см. в разделах Основные сведения об инициализаторах баз данных в Entity Framework Code First и в главе 6 книги Программирование Entity Framework: Code First от Джули Лерман и Роуэн Миллер.

Получите код

Скачивание завершенного проекта

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

Ссылки на другие ресурсы Entity Framework можно найти в разделе ASP.NET Доступ к данным — рекомендуемые ресурсы.

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

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

  • Включенные миграции Code First
  • Развернуто приложение в Azure (необязательно)

Перейдите к следующей статье, чтобы узнать, как создать более сложную модель данных для ASP.NET приложения MVC.