Sto cercando di creare un database di aggiornamento su un primo database con codice EF6. Tutto ciò che ho fatto è creare i miei modelli e il datacontext, eseguire enable-migrations e fatto un addialization InitialCreate. Tutto ha funzionato bene.
Ma il database di aggiornamento sta fallendo in due modi diversi.
Per un po 'ho funzionato, ma stava creando i file di database (cioè i file MDF e di registro) in c: \ Users \. Non li voglio lì. Li voglio nella cartella App_Data di un sito Web MVC che sto costruendo (lo schema del database si trova in una DLL della libreria di classi separata perché deve essere accessibile sia per l'app MVC sia per alcuni oggetti di importazione e massaging in un'app console).
Ho provato a cambiare la posizione dei file del database modificando la stringa di connessione, ma le mie modifiche sono state ignorate (ovvero, i file del database continuano a essere creati in c: \ Users \) o mi sono imbattuto nel secondo errore, "Impossibile aprire il database ... richiesto dal login ... blah blah blah ". Potrei tuttavia aprire il database in SSMS e il mio account utente Windows è il proprietario del database.
Per divertimento ho provato a cancellare e creare il database dall'interno di SSMS. È andato tutto bene ... ma il comando update-database >> ancora << non riesce ad accedere.
Qualunque aiuto per svelare questo casino sarebbe molto apprezzato!
Il costruttore per il mio datacontext:
public CampaignDbContext()
: base( "Council2015", throwIfV1Schema: false )
{
Database.SetInitializer<CampaignDbContext>( null );
}
La stringa di connessione nella libreria di classi app.config:
<connectionStrings>
<add name="Council2015" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=E:\\Programming\\Council2015\\Council2015\\App_Data\\Council2015.mdf;Integrated Security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient"/>
</connectionStrings>
L'eccezione più recente generata da update-database:
Applying explicit migrations: [201503180506326_InitialCreate].
Applying explicit migration: 201503180506326_InitialCreate.
System.Data.SqlClient.SqlException (0x80131904): Cannot open database "Council2015" requested by the login. The login failed.
Login failed for user 'KENSEI\Mark'.
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
...
Cannot open database "Council2015" requested by the login. The login failed.
Login failed for user 'KENSEI\Mark'.
Informazioni addizionali:
C'è qualcosa che ovviamente non capisco sulle stringhe di connessione. Posso far funzionare il database di aggiornamento se fornisco alla stringa di connessione un nuovo nome (ad es. Council2015a) e cambio il parametro di costruttore corrispondente in CampaignDbContext. Ma crea un nuovo database - in c: \ Users \, dove non lo voglio - invece di collegarlo al file di database esistente.
Inoltre, se si eliminano i file del database o si spostano (e si aggiorna il parametro del file allegato), si verifica nuovamente lo stesso errore di accesso.
Quindi qualcosa da qualche parte sta ricordando i database creati in precedenza e "rifiuta" di lasciar andare.
Tutto questo è estremamente controintuitivo (anche perché il nome del database viene chiamato dopo il parametro name nella stringa di connessione).
Mi sono imbattuto nella risposta al problema di base: come creare il database dove lo si desidera, il che sembra aver risolto gli altri problemi che stavo incontrando.
Usa una stringa di connessione che sembra che ti aspetti che debba apparire:
<add name="Council2015" connectionString="Server=(LocalDB)\v11.0; Integrated Security=true; AttachDbFileName=E:\Programming\Council2015\Council2015\App_Data\Council2015.mdf" providerName="System.Data.SqlClient"/>
Ma quando si esegue il database di aggiornamento (dopo aver effettuato le chiamate di add-migration che è necessario eseguire), assicurarsi che la stringa di connessione venga rilevata dal comando update-database .
Sembra che dovrebbe accadere automaticamente. E lo fa, se stai creando il tuo database nel progetto di avvio per la tua soluzione. Perché è lì che update-database cerca le stringhe di connessione, per impostazione predefinita.
Nel mio caso stavo definendo le classi di dati in un progetto di libreria di classi in modo che potessi usarlo in più progetti applicativi. Quindi update-database stava cercando nel posto sbagliato per le stringhe di connessione quando l'ho eseguito all'interno del "contesto" del progetto della libreria di classi.
La selezione della libreria di classi come "Progetto predefinito" nella console di Gestione pacchetti non funziona, nonostante ciò che si pensa (e io), informare il processo di ricerca del database di aggiornamento per le stringhe di connessione.
Invece, specifica esplicitamente il progetto di avvio:
update-database -StartUpProjectName "<class library project name, in my case>"
e voilà!
Ora sul perché un errore nel trovare la stringa di connessione corretta - dal momento che il nome id che stavo usando nel progetto della libreria di classi non compariva nemmeno nell'elenco delle stringhe di connessione nel progetto di avvio della mia soluzione - avrebbe dovuto risultare in un " errore di accesso utente "errore ... beh, questo è oltre me :). E un esempio di pessimo design del software, IMHO.