26

मेरे पास एक एमवीसी 4 ऐप है जिसे मैंने हाल ही में एंटिटी फ्रेमवर्क 5 में अपग्रेड किया है और मैं विकास शैली से माइग्रेशन का उपयोग करने के लिए अपने डेटाबेस को स्थानांतरित करने की कोशिश कर रहा हूं छोड़ने और प्रत्येक रन बनाने के लिए।इकाई फ्रेमवर्क 5 माइग्रेशन: डेटाबेस का प्रारंभिक माइग्रेशन और एकल बीज सेट करना

यहां मैंने अपने ऐप स्टार्ट फ़ंक्शन में क्या किया है।

protected void Application_Start() 
{ 
    Database.SetInitializer(
     new MigrateDatabaseToLatestVersion< MyContext, Configuration >()); 
    ... 
} 

मैं अपने खजाने परियोजना पर Enable-Migrations आदेश भाग गया और मैंने सोचा कि यह एक आरंभिक माइग्रेशन फ़ाइल यह बनाया लेकिन केवल फ़ाइल बना सकेगी था Configuration

जब मैं डेटाबेस इसे बनाता है के माध्यम से अपेक्षित रूप से हटाना पहले कोड और कॉन्फ़िगरेशन फ़ाइल से डेटाबेस बीज। विन्यास फाइल में मैं AddOrUpdate()

लेकिन यह हर बार वेबसाइट शुरू होता है और डुप्लिकेट सभी बीज डेटा बार-बार मेरी Configuration फ़ाइल में बीज समारोह चलाता है करने के लिए सभी Add() कार्यों बदल दिया है।

मैं कल्पना की है कि यह एक initial migration फ़ाइल के रूप में ब्लॉग मैंने पढ़ा सुझाव दिया है कि यह होता है और मैं वहाँ में बीज डेटा डाल सकता है पैदा करेगा लेकिन उसने ऐसा नहीं किया

किसी को कैसे मैं डीबी की स्थापना की जानी चाहिए व्याख्या कर सकते हैं कोड में ताकि यह केवल एक बार बीज हो?


LINK: The migrations blog post I followed


हालांकि यह एफई migrate.exe के बाद से माइग्रेशन चलाने के लिए roundhouse उपयोग करने के लिए बंद कर रहा है उपयोग करने के लिए काफी रोचक है। मैं अभी भी मॉडलों के आधार पर अपने माइग्रेशन को मचान करने के लिए ईएफ का उपयोग करता हूं लेकिन मैंने SQL फ़ाइलों में माइग्रेशन लिखने के लिए थोड़ा कंसोल ऐप लिखा था। मैं फिर अपने रेक निर्माण स्क्रिप्ट के माध्यम से माइग्रेशन करने के लिए राउंडहाउस का उपयोग करता हूं। इसमें थोड़ी अधिक प्रक्रिया शामिल है लेकिन एप्लिकेशन शुरू होने पर फ्लाई पर माइग्रेशन करने के लिए ईएफ का उपयोग करने से कहीं अधिक स्थिर है।

उत्तर

38

यह एक लोकप्रिय पोस्ट साबित हुआ है इसलिए मैंने इसे दूसरों से प्रतिक्रिया के प्रकाश में अपडेट किया है। मुख्य बात यह जानना है कि कॉन्फ़िगरेशन क्लास में बीज विधि हर बार एप्लिकेशन शुरू होती है, जो टेम्पलेट विधि में टिप्पणी का तात्पर्य नहीं है। माइक्रोसॉफ्ट में किसी से इसका जवाब इस post पर क्यों देखें, यह जानने के लिए जेसन Learmouth के लिए धन्यवाद।

यदि आप मुझे पसंद करते हैं, तो केवल लंबित माइग्रेशन होने पर डेटाबेस अपडेट चलाने के लिए चाहते हैं तो आपको थोड़ा और काम करने की आवश्यकता है। अगर आप migrator.GetPendingMigrations() को कॉल करके लंबित माइग्रेशन हैं, तो आप यह पता लगा सकते हैं कि आपको सीटीआर में ऐसा करना है क्योंकि लंबित माइग्रेशन की सूची बीज विधि कहने से पहले साफ़ हो जाती है।

internal sealed class Configuration : DbMigrationsConfiguration<YourDbContext> 
{ 
    private readonly bool _pendingMigrations; 

    public Configuration() 
    { 
     // If you want automatic migrations the uncomment the line below. 
     //AutomaticMigrationsEnabled = true; 
     var migrator = new DbMigrator(this); 
     _pendingMigrations = migrator.GetPendingMigrations().Any(); 
    } 

    protected override void Seed(MyDbContext context) 
    { 
     //Microsoft comment says "This method will be called after migrating to the latest version." 
     //However my testing shows that it is called every time the software starts 

     //Exit if there aren't any pending migrations 
     if (!_pendingMigrations) return; 

     //else run your code to seed the database, e.g. 
     context.Foos.AddOrUpdate(new Foo { bar = true}); 
    } 
} 

मुझे लगता है कि कुछ लोगों को सुझाव दिया है बाहर बिंदु चाहिए वास्तविक 'ऊपर' माइग्रेशन कोड में बीज कोड डाल: जो Migrations.Configuration कक्षा में चला जाता है इस लागू करने के लिए, कोड इस प्रकार है। यह काम करता है, लेकिन इसका मतलब है कि आपको प्रत्येक नए माइग्रेशन में बीज कोड डालना याद रखना होगा और इसकी याद रखना बहुत मुश्किल है, इसलिए मैं ऐसा नहीं करूँगा। हालांकि यदि आपका बीज प्रत्येक माइग्रेशन के साथ बदलता है तो यह जाने का एक अच्छा तरीका हो सकता है।

+0

मैं अनुमान लगाता हूं कि यह हर बार चलता है क्योंकि वास्तव में वास्तविक माइग्रेशन में बीजिंग को लागू करने के बिना वे ऐसा कर सकते हैं। यदि आपका बीज कोड माइग्रेशन के ऊपर() के अंदर था, तो यह केवल एक बार चलाया जाएगा, और यह मेरे लिए अधिक सहज है, क्योंकि आमतौर पर आप कुछ डीबी परिवर्तन करते हैं और स्कीमा – FRoZeN

+0

के इस नए हिस्से में कुछ डेटा बीज करना चाहते हैं आपके पास कोई भी माइग्रेशन नहीं है, इस विधि का उपयोग करके आपकी बीज विधि कभी नहीं चली जाएगी। मैं भी आजकल माइग्रेशन में बीजिंग करना पसंद करता हूं - इस तरह से मुझे पता है कि यह केवल एक बार चलाया जाएगा। – oldwizard

+0

हाय पीसीआरयूआर। वास्तव में आपके पास हमेशा माइग्रेशन होता है क्योंकि प्रारंभिक डेटाबेस को माइग्रेशन माना जाता है, यानी यह डेटाबेस होने के लिए डेटाबेस से माइग्रेट करता है। हालांकि मैं प्रवासन में बीज रखने का लाभ देख सकता हूं। –

2

यह कुछ ऐसा है जो मैंने अतीत में भी सोचा था। मेरे डेटाबेस में कुछ टेबल हैं जो मेरे बीज कार्यक्रम में आबादी प्राप्त करते हैं, और अब मैं यह देखने के लिए जांच करता हूं कि उनमें से एक बीज विधि के भीतर खाली है या नहीं। यदि पंक्तियां हैं, तो बीज विधि नहीं चलती है। अचूक नहीं है, लेकिन चाल है।

+1

यह डेटा डुप्लिकेशंस को रोकने के लिए काम करता है लेकिन एक निकास खंड जोड़ने के एक हैकी समाधान की तरह लगता है। मैं यह देखने के लिए कुछ और दिनों के लिए खुला प्रश्न छोड़ दूंगा कि – Neil

+0

ऐसा करने का एक अच्छा तरीका है, मैं मानता हूं कि यह एक हैकी समाधान है - यह बाहर निकलना नहीं था, और अधिक "यदि कोई पंक्ति मौजूद नहीं है तो कुछ डालें"। फिर आप इसे अतिरिक्त तालिकाओं के लिए दोहरा सकते हैं जिन्हें आप माइग्रेशन में पॉप्युलेट कर सकते हैं। – Richard

6

आप मैन्युअल रूप से माइग्रेशन जोड़ सकते हैं और जो भी बीजिंग कोड चाहते हैं उसे भर सकते हैं? पैकेज प्रबंधक कंसोल समय में:

Add-Migration [Name] 

फिर आप जो आपके माइग्रेशन फ़ोल्डर में आप के लिए बनाया जाता है कि फ़ाइल को संपादित कर सकते हैं।

मेरी परियोजना में मैं वास्तव में रिचर्ड की तरह बीजिंग करता हूं हालांकि संदर्भ कॉन्फ़िगरेशन की बीज विधि में। मुझे वास्तव में कोई वरीयता नहीं है। लेकिन माइग्रेशन अधिक कुशल होना चाहिए कि एप्लिकेशन को यह जांचने की आवश्यकता नहीं है कि अनुप्रयोग शुरू होने पर डेटाबेस में पंक्तियां मौजूद हैं या नहीं। यह जांचने की आवश्यकता है कि माइग्रेशन चलाया गया है, जो तेजी से होना चाहिए।

internal sealed class Configuration : DbMigrationsConfiguration<MyContext> 
{ 
    public Configuration() 
    { 
     // If you want automatic migrations as well uncomment below. 
     // You can use both manual and automatic at the same time, but I don't recommend it. 
     //AutomaticMigrationsEnabled = true; 
     //AutomaticMigrationDataLossAllowed = true; 
    } 

    protected override void Seed(MyContext context) 
    { 
     // This method will be called after migrating to the latest version. 

     // You can use the DbSet<T>.AddOrUpdate() helper extension method 
     // to avoid creating duplicate seed data. 

     context.FontFamilies.AddOrUpdate(
      f => f.Id, 
      new FontFamily { Id = 1, PcName = "Arial" }, 
      new FontFamily { Id = 2, PcName = "Times New Roman" }, 
     }); 

मैं इसे वैश्विक में उपयोग कर रहा हूं।Asax:

public class MvcApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     // Any migrations that haven't been applied before will 
     // automatically be applied on Application Pool restart 

     Database.SetInitializer<MyContext>(
      new MigrateDatabaseToLatestVersion<MyContext, 
      MyApp.Migrations.Configuration>() 
     ); 
    } 
} 
+0

इसे उत्तर के रूप में चिह्नित किया जाना चाहिए। संकेत प्राथमिक कुंजी जांच के साथ "AddOrUpdate" का अधिभार है। मैंने इसे पहली बार नहीं पहचाना .. – Sven

2

this SO question का उत्तर बताता है कि एप चलाने पर हर बार बीज क्यों चलता है।

मैं जॉन स्मिथ विधि का उपयोग करें, लेकिन मैं इस तरह की एक #if ब्लॉक में लंबित माइग्रेशन बयान के लिए चेक डाल दिया है:

#if (!DEBUG) 
      if (!_pendingMigrations) return; 
#endif 

इस तरह जब मैं बीज विधि डिबगिंग कर रहा हूँ हमेशा फिर से आबाद करने के लिए चलाता है मेरी बीज डेटा - जब मैं परीक्षण के दौरान हटा देता हूं, तो उपयोगी होता है लेकिन रिलीज में मुझे पर्फ हिट नहीं मिलता है।

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