2015-08-18 50 views
3

我正在使用SQL Server Express/LocalDB的簡單桌面應用程序。我有一個任意的非特權位置的數據目錄,在那裏我想創建一個數據庫文件。我最初創建了數據庫併爲EF使用生成了一個模型;現在我想使用該模型在任何我想要的地方重新創建數據庫。以編程方式在任意位置創建數據庫

我發現各種類似的帖子,但他們似乎正在刪除和重新創建一個現有的數據庫通過一開始工作的上下文,用於測試目的。我想從一個空目錄開始。

使用here代碼中的摘錄我能夠在磁盤上物理創建一個數據庫文件,使用SQL語句創建新的.mdf和.ldf文件。但他們沒有模式;如果我從.mdf文件中啓動一個上下文實例,然後嘗試計算表中的行數,我會得到一個拋出的異常,因爲該表不存在。

如果我嘗試呼叫ctx.Database.Create(),那麼我得到的錯誤是數據庫無法創建,因爲它已經存在。當然,它只是沒有表格。

如果我最初不使用原始SQL查詢來創建新的空數據庫,並且我嘗試按如下所示創建上下文,並使用filespec指向有效目錄中不存在的.mdf文件, .Create()總是拋出一個異常「數據庫‘’不能創建因爲它已經存在」

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

我怎樣才能EF在我的空數據庫創建表,或者從頭開始創建的文件嗎?

回答

0

經過大量的實驗,以下是我已經結束了,沒有工作的代碼。

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

嘗試使用替代以下:

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

+0

鉭,但試過earlier-因爲在這兩種情況下,它認爲DB存在,'CreateIfNotExists()'什麼都不做,返回false雖然異常的甩不存在,只要我盡力算在第二種情況下,由於沒有文件,並且在第一種情況下出現「對象不存在」或類似情況,因爲打開了數據庫但沒有表格,所以我得到了「底層提供者在打開時失敗」的行數。 –

相關問題