2016-03-17 9 views
5

एंटीटीफ्रेमवर्क माइग्रेशन नए संदर्भ में स्विच करने के बाद बेकार हो जाता है। डीबीएमग्रेटर पहले डेटाबेस उदाहरण से लंबित माइग्रेशन की सूची का उपयोग कर रहा है, जिसका अर्थ यह है कि अन्य डेटाबेस पर कोई माइग्रेशन लागू नहीं होता है, जिसके बाद बीज() के दौरान त्रुटियां होती हैं;डीबीएमग्रेटर डेटाबेस को स्विच करने के बाद लंबित माइग्रेशन का पता नहीं लगाता

  • सी # .NET 4.5 MVC एफई 6
  • एमएस SQL ​​सर्वर 2014 के साथ इस परियोजना, एक ही डेटाबेस मॉडल के कई उदाहरण।
  • माइग्रेशन के साथ CodeFirst दृष्टिकोण।
  • डीबीकॉन्टेक्स्ट प्रारंभकर्ता शून्य पर सेट है।

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

foreach (var connectionString in connectionStrings) 
{ 
    using (var context = new ApplicationDbContext(connectionString)) 
    { 
     //Create database 
     var created = context.Database.CreateIfNotExists(); 

     var conf = new Workshop.Migrations.Configuration(); 
     var migrator = new DbMigrator(conf); 

     migrator.Update(); 

     //initial values 
     conf.RunSeed(context); 
    } 
} 
  • context.Database.CreateIfNotExists(); सही ढंग से काम करता है।
  • migrator.GetLocalMigrations() हमेशा सही मान लौटा रहा है।
  • migrator.GetPendingMigrations() पहले डेटाबेस के बाद खाली सूची लौटा रहा है।
  • migrator.GetDatabaseMigrations() लंबित माइग्रेशन का दर्पण है, पहले डेटाबेस के बाद इसमें खाली डेटाबेस के लिए पूर्ण सूची ईवेंट शामिल है।
  • डीबी इंस्टेंस से डेटा (context.xxx.ToList()) प्राप्त करना पुष्टि करता है कि कनेक्शन ऊपर है और काम कर रहा है, और सही उदाहरण के लिए लिंक।

migrator.Update("migration_name"); के साथ हालिया माइग्रेशन में अपडेट को मजबूर करना कुछ भी नहीं बदलता है। ईएफ स्रोत कोड पढ़कर मैं जो इकट्ठा करता हूं, उससे लंबित माइग्रेशन सूची की जांच होती है, जो इसे दोषपूर्ण परिणाम देती है।

ऐसा लगता है कि कुछ कैशिंग हुड के नीचे जा रही है, लेकिन यह मुझे इसे रीसेट करने का तरीका बताती है।

क्या कई डेटाबेस पर माइग्रेशन करने का कोई तरीका है या फिर यह ईएफ में "डिजाइन द्वारा बग" है?


संपादित करें:

रियल समस्या DbMigrator है अपने उपयोग के लिए नए प्रसंग का निर्माण। यह डिफ़ॉल्ट पैरामीटर रहित कन्स्ट्रक्टर के माध्यम से करता है, जो मेरे मामले में web.Config में डिफ़ॉल्ट (पहले) कनेक्शन स्ट्रिंग पर फ़ॉलबैक था। से

var originalConStr = WebConfigurationManager.ConnectionStrings["ApplicationDbContext"].ConnectionString; 

var setting = WebConfigurationManager.ConnectionStrings["ApplicationDbContext"]; 

var fi = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); 

//disable readonly flag on field 
fi.SetValue(setting, false); 

setting.ConnectionString = temporaryConnectionString; //now it works 

//DO STUFF 

setting.ConnectionString = originalConStr; //revert changes 

Cheat: How do I set a connection string config programatically in .net?


मैं अभी भी आशा है कि किसी को होगा

मैं इस समस्या लेकिन मेरे मामले में आदिम वैकल्पिक हल के लिए अच्छा समाधान नहीं दिख रहा है अस्थायी रूप से संपादित करें डिफ़ॉल्ट कनेक्शन स्ट्रिंग के लिए है असली समाधान ढूंढें ताकि अब मैं आत्म-उत्तर से बचना चाहूंगा।

उत्तर

4

आपको DbMigrationsConfiguration.TargetDatabase संपत्ति को सही ढंग से सेट करने की आवश्यकता है, अन्यथा माइग्रेटर डिफ़ॉल्ट कनेक्शन जानकारी का उपयोग करेगा।

तो सिद्धांत रूप में आप इस

conf.TargetDatabase = new System.Data.Entity.Infrastructure.DbConnectionInfo(...); 

दुर्भाग्य DbConnectionInfo का केवल 2 सार्वजनिक constructors की तरह कुछ कर सकते हैं कर रहे हैं

public DbConnectionInfo(string connectionName) 

connectionName: में कनेक्शन स्ट्रिंग के नाम आवेदन विन्यास।

और

public DbConnectionInfo(string connectionString, string providerInvariantName) 

connectionstring: कनेक्शन स्ट्रिंग कनेक्शन के लिए उपयोग करने के लिए।
प्रदाताInvariantName: कनेक्शन के लिए उपयोग करने के लिए प्रदाता का नाम। SQL सर्वर के लिए 'System.Data.SqlClient' का उपयोग करें।

मुझे लगता है कि आपके पास कनेक्शन स्ट्रिंग है, लेकिन आपको पता नहीं है कि आप providerInvariantName कैसे प्राप्त कर सकते हैं।

अद्यतन: मैं आवश्यक जानकारी लेने का एक अच्छा "आधिकारिक" जिस तरह से मिला नहीं है, इसलिए मैं प्रतिबिंब के माध्यम से internal सदस्यों तक पहुँचने के साथ एक हैक का उपयोग कर समाप्त कर दिया, लेकिन अभी भी IMO यह की तुलना में एक काफी अधिक सुरक्षित है क्या आप का इस्तेमाल किया है:

var internalContext = context.GetType().GetProperty("InternalContext", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(context); 
var providerName = (string)internalContext.GetType().GetProperty("ProviderName").GetValue(internalContext); 
var conf = new Workshop.Migrations.Configuration(); 
conf.TargetDatabase = new System.Data.Entity.Infrastructure.DbConnectionInfo(connectionString, providerName); 
+0

हममम ... DbContextConfiguration नहीं DbMigrationsConfiguration के रूप में काम करने के लिए (DbMigrator निर्माता यह चाहता है) चाहता है तो व्यावहारिक दृष्टिकोण यहाँ विफल रहता है। कस्टम कनेक्शन जानकारी विफल हो जाती है क्योंकि DbMigrator इसे अनदेखा करता है और मेरे संदर्भ के पैरामीटर रहित कन्स्ट्रक्टर को कॉल करता है जो डिफ़ॉल्ट रूप से web.config से कनेक्शन स्ट्रिंग का उपयोग करता है। (यह मेरी असली समस्या है, ऐसा प्रतीत होता है)। अंत में मैं अद्यतन की अवधि के लिए प्रतिबिंब के माध्यम से बस 'ebConfigurationManager.ConnectionStrings ["ApplicationDbContext"] संपादित करें। मुझे उम्मीद है कि वहां बेहतर तरीका है (सिंगलेट्स/स्थिर क्षेत्र बेहतर नहीं लगता है)। – PTwr

+0

ओह, आप खूनी सही हैं! –

+0

नहीं, मैं नहीं हूं। मेरी टीम लीडर थी; पी – PTwr

संबंधित मुद्दे

 संबंधित मुद्दे