2013-03-28 3 views
10

चलाएं मैं एंटिटी फ्रेमवर्क कोड प्रथम माइग्रेशन का उपयोग कर रहा हूं, और मेरे पास एक परिदृश्य है जहां मैं एकीकरण परीक्षणों का एक सूट चलाने के लिए चाहता हूं।ईएफ 5, कोड फर्स्ट - एक नया डेटाबेस बनाएं और सभी माइग्रेशन प्रोग्रामेटिक रूप से

  1. ड्रॉप मौजूदा परीक्षण डेटाबेस (यदि हो तो)
  2. एक नया परीक्षण बनाएँ: हर बार परीक्षण चलाने, मैं

    चरणों होना चाहिए डेटाबेस फिर से बनाने, और सभी माइग्रेशन लागू करना चाहते हैं डेटाबेस, और सभी माइग्रेशन

  3. बीज डेटा

यह है कि मैं करने के लिए माइग्रेशन जोड़ दिया है एक मौजूदा परियोजना है लागू होते हैं, और मैं सक्षम-माइग्रेशन एक "InitialCreate" माइग्रेशन वें बनाने के लिए इस्तेमाल किया कमान मेरे डेटाबेस में सभी टेबल जोड़ने के लिए कोड शामिल है।

public void InitializeDatabase(MyContext context) 
{ 
    //delete any existing database, and re-create 
    context.Database.Delete(); 
    context.Database.Create();    

    //apply all migrations 
    var dbMigrator = new DbMigrator(new Configuration()); 
    dbMigrator.Update(); 

    //seed with data 
    this.Seed(context); 

    context.SaveChanges(); 
} 

मेरी InitialCreate प्रवास के Up विधि इस कोड से बुलाया नहीं हो रही है, जो नहीं है कि मैं क्या उम्मीद:

कोड अपने कस्टम IDatabaseInitializer में इस प्रकार है। इसके बजाय, सभी तालिकाएं बनाई जाती हैं जब Database.Create() विधि कहा जाता है। मुझे चलाने के लिए InitialCreate माइग्रेशन की आवश्यकता है क्योंकि संग्रहित प्रक्रियाओं को बनाने के लिए मेरे पास अतिरिक्त कोड है।

तो मेरे प्रश्न यह है कि, मैं प्रोग्रामेटिक रूप से एक नया डेटाबेस कैसे बना सकता हूं और सभी माइग्रेशन (प्रारंभिक क्रिएट माइग्रेशन समेत) कैसे चला सकता हूं?

उत्तर

4

निम्नलिखित कोड ने मुझे प्रश्न में उल्लिखित मेरे एकीकरण परीक्षण परिदृश्य की आवश्यकताओं को पूरा करने की अनुमति दी है, लेकिन निश्चित रूप से एक बेहतर तरीका है?

public void InitializeDatabase(MyContext context) 
{ 
    //delete any existing database, and re-create 
    context.Database.Delete(); 

    var newDbConnString = context.Database.Connection.ConnectionString; 
    var connStringBuilder = new SqlConnectionStringBuilder(newDbConnString); 
    var newDbName = connStringBuilder.InitialCatalog; 

    connStringBuilder.InitialCatalog = "master"; 

    //create the new DB 
    using(var sqlConn = new SqlConnection(connStringBuilder.ToString())) 
    { 
     using (var createDbCmd = sqlConn.CreateCommand()) 
     { 
      createDbCmd.CommandText = "CREATE DATABASE " + newDbName; 
      sqlConn.Open(); 
      createDbCmd.ExecuteNonQuery(); 
     } 
    } 

    //wait up to 30s for the new DB to be fully created 
    //this takes about 4s on my desktop 
    var attempts = 0; 
    var dbOnline = false; 
    while (attempts < 30 && !dbOnline) 
    { 
     if (IsDatabaseOnline(newDbConnString)) 
     { 
      dbOnline = true; 
     } 
     else 
     { 
      attempts++; 
      Thread.Sleep(1000); 
     } 
    } 

    if (!dbOnline) 
     throw new ApplicationException(string.Format("Waited too long for the newly created database \"{0}\" to come online", newDbName)); 

    //apply all migrations 
    var dbMigrator = new DbMigrator(new Configuration()); 
    dbMigrator.Update(); 

    //seed with data 
    this.Seed(context); 

    context.SaveChanges(); 
} 

private bool IsDatabaseOnline(string connString) 
{ 
    try 
    { 
     using (var sqlConn = new SqlConnection(connString)) 
     { 
      sqlConn.Open(); 
      return sqlConn.State == ConnectionState.Open; 
     } 
    } 
    catch (SqlException) 
    { 
     return false; 
    } 
} 
1

बस "डेटाबेस बनाने के" कदम को हटा दें और अपने दम पर माइग्रेशन का उपयोग करें। मैंने GitHub पर नमूना प्रोजेक्ट लगाया है, लेकिन महत्वपूर्ण बिट

Configuration config = new Configuration(); 
DbMigrator migrator = new DbMigrator(config); 

foreach (string s in migrator.GetPendingMigrations()) 
{ 
    migrator.Update(s); 
} 
संबंधित मुद्दे