7

Я разрабатываю веб-приложение в ASP.NET с использованием первых миграций кода. Он работает нормально локально, но после развертывания в Azure сначала выполняются первые миграции кода. Я несколько раз следил за this tutorial, но я не смог определить, что не так в моей настройке. Вот соответствующий код:Первичные миграции кода EntityFramework не выполняются после развертывания в Azure

DB Контекст:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) {} 

    public DbSet<BC_Instance> BiocloudInstances { get; set; } 

    static ApplicationDbContext() {} 

    public static ApplicationDbContext Create() 
    { 
     return new ApplicationDbContext(); 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     var conv = new AttributeToTableAnnotationConvention<SoftDeleteAttribute, string>(
      "SoftDeleteColumnName", 
      (type, attributes) => attributes.Single().ColumnName); 

     modelBuilder.Conventions.Add(conv); 
    } 
} 

строки подключения:

(он заменяется на публикацию, но только в том случае)

<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=bcplatform2;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /></connectionStrings> 

Code Fi Первые Миграции конфигурации

internal sealed class Configuration : DbMigrationsConfiguration<bcplatform2.Models.ApplicationDbContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
    } 

    protected override void Seed(bcplatform2.Models.ApplicationDbContext context) 
    { 
     var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(context)); 
     var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole>(context)); 
     const string name = {name here}; 
     const string password = {pass here}; 
     const string adminRole = {role}; 
     string[] roles = new string[] { adminRole, ApplicationRole.DefaultRoleName }; 

     foreach (string role in roles) 
     { 
      if (!context.Roles.Any(r => r.Name == role)) 
      { 
       roleManager.CreateAsync(new ApplicationRole(role)); 
      } 
     } 

     if (!context.Users.Any(u => u.UserName == name)) 
     { 
      var user = new ApplicationUser { UserName = name, Email = name, credit = 10 }; 

      userManager.Create(user, password); 
      userManager.AddToRole(user.Id, adminRole); 
      userManager.SetLockoutEnabled(user.Id, false); 
     } 
    } 
} 

Мастер публикации enter image description here

Entity рамки раздел в развернутом Web.config

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
    <parameters> 
     <parameter value="mssqllocaldb" /> 
    </parameters> 
    </defaultConnectionFactory> 
    <providers> 
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
    <contexts> 
    <context type="bcplatform2.Models.ApplicationDbContext, bcplatform2"> 
     <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[bcplatform2.Models.ApplicationDbContext, bcplatform2], [bcplatform2.Migrations.Configuration, bcplatform2]], EntityFramework, PublicKeyToken={token}"> 
     <parameters> 
      <parameter value="DefaultConnection_DatabasePublish" /> 
     </parameters> 
     </databaseInitializer> 
    </context> 
    </contexts> 
</entityFramework> 

строки подключения в развернутом Web.config

<connectionStrings> 
    <add name="DefaultConnection" connectionString="Data Source=tcp:{serverid}.database.windows.net,1433;Initial Catalog={dbid};User Id={user};Password={password}" providerName="System.Data.SqlClient" /> 
    <add name="DefaultConnection_DatabasePublish" connectionString="Data Source=tcp:{serverid}.database.windows.net,1433;Initial Catalog={dbid};User ID={user};Password={password}" providerName="System.Data.SqlClient" /> 
</connectionStrings> 
+0

Вы проверили развернутый файл web.config? – ErikEJ

+0

Нет, но соединение с базой данных не является проблемой. Проблема заключается в том, что миграция не применяется и не высевается db. Я посмотрю, хотя – nest

+0

@ErikEJ Я изменил Вопрос, чтобы включить эту информацию. В самом деле, я не уверен, что это правильно, где сказано '<параметр value =" mssqllocaldb "/>' или ' nest

ответ

1

Проблема была на методе семян:

protected override void Seed(bcplatform2.Models.ApplicationDbContext context) 
{ 
    var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(context)); 
    var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole>(context)); 
    const string name = {name here}; 
    const string password = {pass here}; 
    const string adminRole = {role}; 
    string[] roles = new string[] { adminRole, ApplicationRole.DefaultRoleName }; 

    foreach (string role in roles) 
    { 
     if (!context.Roles.Any(r => r.Name == role)) 
     { 
      roleManager.CreateAsync(new ApplicationRole(role)); 
     } 
    } 

    if (!context.Users.Any(u => u.UserName == name)) 
    { 
     var user = new ApplicationUser { UserName = name, Email = name, credit = 10 }; 

     userManager.Create(user, password); 
     userManager.AddToRole(user.Id, adminRole); 
     userManager.SetLockoutEnabled(user.Id, false); 
    } 
} 

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

Некоторые советы, чтобы избежать подобных проблем в будущем, не будут использовать параметры «Использовать эту строку соединения во время выполнения» и «Выполнение первых миграций кода» в мастере публикации. Если что-то пойдет не так, вывод не всегда будет показывать ошибку, и он мало контролирует изменение Web.config.

Вместо этого замените строку подключения в Web.config перед публикацией или настройте Web.Debug.config и Web.Release.config соответственно.

+0

Это имеет смысл. Спасибо за информацию. –

+0

да, но я не знаю, что с ним не так, так как тот же код успешно завершается на более поздней стадии, но он не работает при операции семени – nest

7

Вы можете обновить файл Web.config в решении

Это не обязательно предоставлять строку подключения в разделе «контекст», потому что вы уже обеспечивают его в ApplicationDbContext конструктору.

Кроме того, с помощью этой конфигурации вы можете снять флажок «Выполнять первую миграцию кода» в «Мастере публикаций».

Ваш EF раздел должен выглядеть следующим образом (наиболее важным является раздел «контекст»):

<entityFramework> 
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
    <parameters> 
    <parameter value="mssqllocaldb" /> 
    </parameters> 
</defaultConnectionFactory> 
<providers> 
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
</providers> 
<contexts> 
    <context type="TestWebApp.Models.AppContext, TestWebApp"> 
    <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[TestWebApp.Models.AppContext, TestWebApp], [TestWebApp.Migrations.Configuration, TestWebApp]], EntityFramework" /> 
    </context> 
</contexts> 

2

Это не работает, потому что вы могли бы создать/выбранное другое соединение в развертывании мастер. То же самое подтверждается в развернутой строке соединения, где вы можете увидеть две строки подключения.

Вторая строка подключения также referecened в EF seciton -

И, в контексте вы использовали первый ConnectionString - общественное ApplicationDbContext(): базовый ("DefaultConnection", throwIfV1Schema: ложь) {}

Изменение названия здесь решит вашу проблему.

+0

спасибо @jitendra. Это имеет смысл. Но знаете ли вы, как я могу избавиться от этой «другой» связи? Я никогда не собирался его создавать, на самом деле он был создан для меня во время процесса развертывания, я считаю. Я хотел бы использовать «DefaultConnection» для разработки и производства. – nest

+0

Попробуйте снять флажок с помощью этой опции строки подключения в Мастере развертывания, так как у вас ее уже есть. Это может помочь. –

+0

Вы смогли это решить? Я хотел бы услышать отзывы. –

1

Если вы хотите иметь больше контроля над процессом миграции, вы можете справиться с миграцией в старте .Auth пути создания контекста и использовать DBMigrator() класса применять все ожидающие миграции:

//Get the connection string 
var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"]; 

//Instanciate the sql connection string builder 
var builder = new System.Data.SqlClient.SqlConnectionStringBuilder(connectionString.ConnectionString); 

//Create your context 
var dbContext = new ApplicationDbContext(builder.ConnectionString); 

//Check for null (Handle issue here). 
if (dbContext == null) return; 

//Get your configuration and specify the target database 
var config = new Migrations.Configuration(); 
config.TargetDatabase = new DbConnectionInfo(builder.ConnectionString, "System.Data.SqlClient"); 

//Create the migrator using your config 
var mig = new DbMigrator(config); 

//Check for any pending migration to speed up the process and Update 
//The migration will be applied here each time the application is published on azure 
if(mig.GetPendingMigrations().Any())mig.Update(); 

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

Смежные вопросы