Поделиться через


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

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

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

Рекомендуется использовать непрерывный процесс интеграции с системой управления версиями для развертывания, но в этом руководстве не рассматриваются эти разделы. Дополнительные сведения см. в статье Развертывание облачной микрослужбы .NET автоматически с помощью GitHub Actions и Azure Pipelines.

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

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

Необходимые компоненты

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

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

Этот способ для обеспечения синхронизации базы данных с моделью данных хорошо работает до развертывания приложения в рабочей среде. Когда приложение работает в рабочей среде, обычно сохраняет данные, которые нужно сохранить, и вы не хотите терять все, когда вы вносите изменения, например добавление нового столбца. Функция "Первая миграция кода" решает эту проблему, позволяя 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

При удалении и повторном создании базы данных для каждого изменения модели данных используется метод инициализатора Seed для вставки тестовых данных, так как после каждого изменения модели база данных удаляется и все тестовые данные теряются. При первой миграции кода тестовые данные сохраняются после изменений базы данных, поэтому, как правило, не требуется тестовые данные в методе 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)
    

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

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

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

    Код, создающий 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 свойство сущности в памяти.

    Код, добавляющий каждую EnrollmentEnrollmentsAddOrUpdate сущность в набор сущностей, не использует метод. Он проверяет, существует ли сущность и вставляет сущность, если она не существует. Этот подход сохранит изменения, внесенные в оценку регистрации с помощью пользовательского интерфейса приложения. Код циклит по каждому элементу 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 в файле с именем <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 проверяет, соответствует ли база данных модели данных. Если имеется несоответствие, код сначала автоматически создает базу данных (если она еще не существует) или обновляет схему базы данных до последней версии (если база данных существует, но не соответствует модели). Если приложение реализует метод Migrations Seed , метод запускается после создания базы данных или обновления схемы.

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

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

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

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

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

Вы развернете базу данных в базе данных SQL Azure. База данных 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. Выберите раздел "Ценовая категория " и выберите "Бесплатный". Если требуются дополнительные ресурсы, база данных может быть масштабирована в любое время. Дополнительные сведения о ценах на SQL Azure см. в База данных SQL Azure ценах.

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

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

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

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

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

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

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

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

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

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

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

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

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

    Students_index_page_with_paging

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

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

Файл web.config excerpt

Процесс развертывания также создал новую строка подключения (SchoolContext_DatabasePublish) для миграции кода для обновления схемы базы данных и заполнения базы данных.

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

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

Примечание.

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

Остановка элемента меню службы приложений

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

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

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

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

update-database -target MigrationName

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

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

Add-migration MigrationName -ignoreChanges

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

Инициализаторы кода

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

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

Получение кода

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

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

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

Следующие шаги

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

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

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