Programmiermäßig erstellen Sie DB von vorne an beliebiger Stelle

Ich arbeite an einer einfachen Desktop-App, die SQL server Express / LocalDB verwendet. Ich habe ein dataverzeichnis in einem beliebigen nichtprivilegierten Ort und dort möchte ich eine databasedatei erstellen. Ich habe zunächst die database erstellt und ein model für EF erstellt. Jetzt möchte ich dieses model verwenden, um die database neu zu erstellen, wo immer ich es will.

Ich habe eine Vielzahl von Posts gefunden, die ähnlich sind, aber sie scheinen, eine vorhandene database zu löschen und neu zu erstellen, und zwar über einen Kontext, der für Testzwecke arbeitet. Ich möchte aus einem leeren Verzeichnis starten.

Mit Auszügen aus dem Code hier bin ich in der Lage, physisch erstellen Sie eine database-file auf dem dataträger, mit den SQL-statementen, um die neuen .mdf und .ldf-fileen zu erstellen. Aber sie haben nicht das Schema; Wenn ich eine Kontext-Instanz aus der .mdf-file starten und dann versuchen, die Anzahl der Zeilen in einer Tabelle zu zählen, bekomme ich eine exception geworfen, weil die Tabelle nicht existiert.

Wenn ich versuche ctx.Database.Create() dann bekomme ich den Fehler, dass die database nicht erstellt werden kann, weil es bereits vorhanden ist. Was natürlich das tut, nur ohne Tische.

Wenn ich die rohen SQL-Abfragen zunächst nicht verwenden, um die neue, leere, database zu erstellen und ich versuche, den Kontext wie folgt zu erstellen, wobei filepec auf eine nicht vorhandene .mdf-file in einem gültigen Verzeichnis zeigt, das .Create () immer eine exception austriggers "database" kann nicht erstellt werden, da es bereits existiert "

 string connectionString = "Data Source=(LocalDB)\\v11.0;AttachDbFilename=" + fileSpec; EventsListDBEntities ctx = new EventsListDBEntities(); ctx.Database.Connection.ConnectionString = connectionString; ctx.Database.Create(); ctx.Database.Initialize(true); 

Wie bekomme ich EF, um die Tabellen in meinem leeren DB zu erstellen oder die fileen von Grund auf neu zu erstellen?

Versuchen Sie es mit folgendem:

 string connectionString = "Data Source=(LocalDB)\\v11.0;AttachDbFilename=" + fileSpec; EventsListDBEntities ctx = new EventsListDBEntities(); ctx.Database.Connection.ConnectionString = connectionString; ctx.Database.CreateIfNotExists(); // Change this line. ctx.Database.Initialize(true); 

https://msdn.microsoft.com/en-us/library/system.data.entity.database.createifnotexists%28v=vs.113%29.aspx#M:System.Data.Entity.Database.CreateIfNotExists

Nach vielen Experimenten, hier ist der Code, den ich damit beendet habe, macht den Job.

 string connectionString = "Data Source=(LocalDB)\\v11.0;AttachDbFilename=" + fileSpec + ";database=EventsListDB"; /* We can't go straight into the context and create the DB because * it needs a connection to "master" and can't create it. Although this * looks completely unrelated, under the hood it leaves behind something * that EF can pick up and use- and it can't hurt to delete any references * to databases of the same name that may be lurking in other previously * used directories. */ SqlConnectionStringBuilder masterCSB = new SqlConnectionStringBuilder(connectionString); masterCSB.InitialCatalog = "master"; masterCSB.AttachDBFilename = ""; using (var sqlConn = new SqlConnection(masterCSB.ToString())) { sqlConn.Open(); using (var cmd = sqlConn.CreateCommand()) { bool done = false; int attempt = 0; do { try { cmd.CommandText = String.Format( "IF EXISTS (Select name from sys.databases " + "WHERE name = '{0}') " + "DROP DATABASE {0}", "EventsListDB"); cmd.ExecuteNonQuery(); done = true; } catch (System.Exception ex) { /* We sometimes get odd exceptions that're probably because LocalDB hasn't finished starting. */ if (attempt++ > 5) { throw ex; } else Thread.Sleep(100); } } while (!done); } } /* Now we can create the context and use that to create the DB. Note that * a custom constructor's been added to the context exposing the base * constructor that can take a connection string- changing the connection * string after the default constructor reads it from App.config isn't * sufficient. */ EventsListDBEntities ctx = new EventsListDBEntities(connectionString); ctx.Database.Create(); int numRecords = ctx.EventLists.Count(); //See if it really worked.