Как развернуть ASP.NET сайт MVC с существующей базой данных для веб-приложений Azure?


Структура вопроса: сначала я даю структуру и конфигурации моего проекта ASP-MVC-4, затем описываю, как я развертываю свой сайт в веб-приложениях Azure и, наконец, представляю свою ошибку и вопрос. Моя проблема связана с конфликтами с EF Code-First Migrations во время развертывания Azure.


Мой проект ASP MVC 4 и конфигурации:

Я использую Visual Studio 2015-U3. Я уже ASP.NET сайт MVC 4. Целевая структура: .NET Framework 4.5. Сайт имеет свою собственную базу данных и работает локально и взаимодействует с базой данных ((LocalDb)v11.0). Я использовал подход Entity Framework Code-First для создания и заполнения данных.

Моя БД строка подключения в Web.config:

 <add name="DefaultConnection" connectionString="Data Source=(LocalDb)v11.0;Initial Catalog=OnlineAuctionDb;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|OnlineAuctionDb.mdf" providerName="System.Data.SqlClient"/>

(он заменен наpublish , но на всякий случай)

Мой DbContext класс:

    public partial class AuctionDataContext : DbContext
    {       
        public AuctionDataContext() : base("DefaultConnection") 
        {    }

        public DbSet<Auction> Auctions { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<User> Users { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<Bid> Bids { get; set; }
        public DbSet<ItemImage> Images { get; set; }
        public DbSet<Detail> Details { get; set; }
        public DbSet<DetailValue> DetailValues { get; set; }
   }

У меня есть класс DataContextInitializer, где я инициализирую все необходимые данные.

 public class DataContextInitializer : DropCreateDatabaseAlways<AuctionDataContext>
    {
        protected override void Seed(AuctionDataContext context)
        { 
           ***All my initializations go here 
        }
    }

Поскольку я не использую обычный SQL и вместо этого использовать Entity Framework Code First I enabled миграции . В классе Configuration и конфигурации .cs файл, который я написал:

 public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

Развертывание в Azure

Теперь я переключаюсь на развертывание веб-приложений Azure. Я развернул сайт на веб-сайтах Azure через VS с помощью кнопкиPublish .

Шаг за шагом:

Я выбрал веб-приложения Microsoft Azure:

Введите описание изображения здесь


Затем я выбрал свой созданный сайт auctionWeb (все здесь была настроена автоматически):

Введите описание изображения здесь


На следующем шаге я выбрал только Execute Code First Migrations. строка соединения (соединение по умолчанию) была настроенаавтоматически . Он был настроен на:

Data Source=tcp:auction-tserver.database.windows.net,1433;Initial Catalog=OnlineAuctionDb;User Id=auctionAdmin@auction-tserver.database.windows.net;Password=mypassword

Введите описание изображения здесь


На последнем шаге я нажал кнопку опубликовать :

Введите описание изображения здесь


Вывод в браузере:

Я получил ошибку :

Ошибка Сервера в применении. недопустимое имя столбца "FirstName". Недопустимое имя столбца "фамилия". Недопустимое имя столбца "электронная почта". Страна недопустимое имя столбца''. Недействительный имя столбца "состояние". Город недопустимое имя столбца''. Недопустимое имя столбца "Адрес". Недопустимое имя столбца "PostalCode". Недопустимое имя столбца "Телефон". Недопустимое имя столбца "пароль".

Описание: необработанное исключение возникло во время выполнения текущего веб-запроса. Пожалуйста, просмотрите стек трассировка для большего информация об ошибке и о том, где она возникла в коде.

Ошибка источника: необработанное исключение было сгенерировано во время выполнения текущего веб-запроса. Информация о происхождении и местоположение исключения может быть определено с помощью исключения трассировка стека ниже.

Трассировка стека:

[SqlException (0x80131904): Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Email'.
Invalid column name 'Country'.
Invalid column name 'State'.
Invalid column name 'City'.
Invalid column name 'Address'.
Invalid column name 'PostalCode'.
Invalid column name 'Phone'.
Invalid column name 'Password'.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +2442634
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5766568
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +285
   System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +4162
   System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption) +255
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) +2031
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) +911
   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) +359
   System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +286
   WebMatrix.Data.Database.Execute(String commandText, Object[] args) +111
   WebMatrix.WebData.DatabaseWrapper.Execute(String commandText, Object[] parameters) +14
   WebMatrix.WebData.SimpleMembershipProvider.CreateUserRow(IDatabase db, String userName, IDictionary`2 values) +695
   WebMatrix.WebData.SimpleMembershipProvider.CreateUserAndAccount(String userName, String password, Boolean requireConfirmation, IDictionary`2 values) +65
   WebMatrix.WebData.WebSecurity.CreateUserAndAccount(String userName, String password, Object propertyValues, Boolean requireConfirmationToken) +70
   OnlineAuction.MvcApplication.SetSecurityOptions() +322
   OnlineAuction.MvcApplication.Application_Start() +51

[HttpException (0x80004005): Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Email'.
Invalid column name 'Country'.
Invalid column name 'State'.
Invalid column name 'City'.
Invalid column name 'Address'.
Invalid column name 'PostalCode'.
Invalid column name 'Phone'.
Invalid column name 'Password'.]
   System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +9982013
   System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +118
   System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +172
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +336
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +296

[HttpException (0x80004005): Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Email'.
Invalid column name 'Country'.
Invalid column name 'State'.
Invalid column name 'City'.
Invalid column name 'Address'.
Invalid column name 'PostalCode'.
Invalid column name 'Phone'.
Invalid column name 'Password'.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9963380
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +101
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +254

Вопрос:

Почему я получаю ошибку? Как правильно развернуть ASP.NET сайт MVC 4 to Microsoft Azure Web Apps cloud, когда я использую EF Code-first, чтобы база данных и сайт работали вместе. На localhost все работает.


Обновление 1:

Когда я захожу в настройки своей базы данных на портале Azure и открываю строки подключения к базе данных, я вижу следующую строку:

Server=tcp:auction-tserver.database.windows.net,1433;Initial Catalog=OnlineAuctionDb;Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

Введите описание изображения здесь

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


Обновление 2:

В Глобальном.asax файл в Application_Start() методе I имел эту строку кода:

 System.Data.Entity.Database.SetInitializer(new OnlineAuction.Models.Entities.DataContextInitializer());

Теперь я изменил его на:

System.Data.Entity.Database.SetInitializer(new System.Data.Entity.MigrateDatabaseToLatestVersion<AuctionDataContext, Configuration>());
Я перенес все свои инициализации из класса DataContextInitializer в класс Configuration (методSeed()).

Итак, мой DataContextInitializer , который выглядел так:

 public class DataContextInitializer : DropCreateDatabaseAlways<AuctionDataContext>
        {
            protected override void Seed(AuctionDataContext context)
            { 
               ***All my initializations go here 
            }
        }

Больше не нужен. Таким образом, классы Configuration и DataContextInitializer больше не конфликтуют.

Теперь все мои инициализации находятся в Configuration класс:

   public class Configuration : DbMigrationsConfiguration<OnlineAuction.Models.Entities.AuctionDataContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(AuctionDataContext context)
        { 
            ***All my initializations go here 
        }
    }

Я также установил значение false AutomaticMigrationsEnabled вариант.

Но я не уверен, что делать с checkbox Execute Code First Migrations (runs on application start) во время процесса website Publish. Нужно ли мне сейчас его выключать?

Меня путают со всеми конфликтами миграции кода в первую очередь. Это все еще не работает.

1 2

1 ответ:

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

Примечание: на скриншоте мы могли видеть, что в таблице пользователей есть только два свойства.

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

Измените стратегию инициализации базы данных ниже в Application_Start , Как вы упомянули:

System.Data.Entity.Database.SetInitializer(new System.Data.Entity.MigrateDatabaseToLatestVersion<AuctionDataContext, Configuration>());

Переместите инициализацию в функции SetSecurityOptions в нижнюю часть функции Seed() внутри класса Configuration.

Примечание: поскольку миграция включена, необходимо либо добавить ожидающие изменения модели в миграцию на основе кода, либо включить автоматическую миграцию для обновления базы данных. Итак, вам нужно установить DbMigrationsConfiguration.AutomaticMigrationsEnabled в true чтобы включить автоматическую миграцию.

Результат: http://bruce-chen-001.azurewebsites.net/

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