7

Sto sviluppando un'applicazione Web in ASP.NET utilizzando le migrazioni di prima del codice. Funziona bene localmente ma dopo la distribuzione in Azure, le migrazioni prima del codice non vengono eseguite. Ho seguito alcune volte lo this tutorial, ma non sono stato in grado di individuare ciò che è sbagliato nella mia configurazione. Ecco il codice rilevante:Le migrazioni del primo codice EntityFramework non vengono eseguite dopo la distribuzione in Azure

DB Contesto:

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); 
    } 
} 

stringhe di connessione:

(si è sostituito il pubblicare, ma solo nel caso)

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

Codice Fi prime migrazioni di configurazione

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); 
     } 
    } 
} 

procedura guidata di pubblicazione enter image description here

Entity sezione quadro in schierato 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> 

stringhe di connessione in schierato web.config

0.123.
<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

Hai ispezionato il file web.config distribuito? – ErikEJ

+0

No, ma la connessione con il database non è un problema. Il problema è che la migrazione non viene applicata, né il db seminato. Lo cercherò anche se – nest

+0

@ErikEJ Ho modificato la domanda per includere queste informazioni. Infatti non sono sicuro che sia corretto dove dice '' o ' nest

risposta

1

il problema era sul metodo di semi:

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); 
    } 
} 

non è apparsa completa, ma non ha mostrato alcun errore sull'uscita pubblicazione rendendo l'errore difficili da individuare. Ho rimosso il metodo seed e le migrazioni hanno funzionato.

Alcuni consigli per evitare problemi simili in futuro non sarebbero utilizzare le opzioni "Usa questa stringa di connessione in fase di esecuzione" e "Esegui migrazioni prima del codice" dalla procedura guidata di pubblicazione. Se qualcosa va storto, l'output non mostra sempre un errore e dà poco controllo su come viene modificato Web.config.

Invece, sostituire la stringa di connessione in Web.config prima di pubblicare o configurare Web.Debug.config e Web.Release.config di conseguenza.

+0

Questo ha senso. Grazie per l'informazione. –

+0

sì ma non so cosa c'è che non va visto che lo stesso codice viene completato con successo in una "fase successiva" ma fallisce nell'operazione seed – nest

7

È possibile aggiornare il file web.config in Solution

non è necessario fornire stringa di connessione sezione interna "contesto", perché già fornirlo nel costruttore ApplicationDbContext.

Inoltre, con questa configurazione, è possibile deselezionare "Esegui prima migrazione del codice" in Pubblicazione guidata.

vostra sezione EF dovrebbe essere simile a questo (più importante è la sezione "contesto"):

<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

Non funziona perché si potrebbe avere creato/selezionato altra connessione in Distribuire procedura guidata. Lo stesso è confermato nella stringa di connessione distribuita in cui è possibile visualizzare due stringhe di connessione.

La seconda stringa di connessione è anche referecened in EF seciton -

E, nel contesto si è utilizzato prima connectionstring - ApplicationDbContext pubblica(): base ("DefaultConnection", throwIfV1Schema: false) {}

Cambiare il nome qui risolverà il problema.

+0

grazie @jitendra. Questo ha senso. Ma sai come posso sbarazzarmi di questa "altra" connessione? Non ho mai avuto intenzione di crearne uno, infatti è stato creato per me durante il processo di distribuzione che credo. Vorrei utilizzare "DefaultConnection" per lo sviluppo e la produzione. – nest

+0

Provare a deselezionare l'utilizzo di questa opzione di stringa di connessione in Distribuzione guidata, poiché ne avete già uno. Questo potrebbe aiutare. –

+0

Sei riuscito a risolverlo? Mi piacerebbe sentire il feedback. –

1

se si desidera avere maggiore controllo sul processo di migrazione, è possibile gestire la migrazione nell'avvio .Auth creando il contesto e utilizzare il DBMigrator() classe per applicare alcuna migrazione in sospeso:

//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(); 

Anche se questo non può risolvere il problema direttamente, esso permette un maggiore controllo e si dovrebbe essere in grado di vedere se il la migrazione non viene applicata con un piccolo lavaggio.