2012-02-02 10 views
21

मैं कई कोड-प्रथम डीबी कॉन्टैक्स के साथ ईएफ 4.3 माइग्रेशन का उपयोग करने की कोशिश कर रहा हूं। मेरा आवेदन कई प्लगइन में विभाजित है, जो संभवतः उनके डोमेन के संबंध में अपना स्वयं का डीबीकॉन्टेक्स्ट है। एप्लिकेशन को एक एकल एसक्यूएल-डेटाबेस का उपयोग करना चाहिए।ईएफ 4.3 एक डेटाबेस में एकाधिक डीबीकॉन्टेक्स के साथ ऑटो-माइग्रेशन

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

तो मेरे सवाल है:

  • मैं कैसे माइग्रेशन-विन्यास सिर्फ टेबल उनकी संगत संदर्भ में परिभाषित की देखभाल और अन्य सभी अकेला छोड़ने के लिए बता सकते हैं?
  • एक ही डेटाबेस में ऑटो-माइग्रेशन के साथ एकाधिक DbContexts से निपटने के लिए सही वर्कफ़्लो क्या है?

धन्यवाद!

+0

यह बहुत ही रोचक सवाल है। मुझे आश्चर्य है कि एकाधिक संदर्भ समर्थन माइग्रेशन उपयोग मामलों का हिस्सा था। –

+2

मुझे अत्यधिक संदेह है कि बहु संदर्भ ऑटो माइग्रेशन के साथ काम कर सकते हैं, यह डीबी को अद्यतन करने के लिए डिज़ाइन किया गया है, संदर्भ के समान दिखने के लिए। माइग्रेशन उत्पन्न करने के लिए अलग-अलग डेटाबेस के खिलाफ, मैन्युअल माइग्रेशन का उपयोग करके प्लगइन विकसित करने के लिए आपके पास अधिक भाग्य हो सकता है, फिर उन्हें सभी को उसी डीबी पर लागू करें। – Betty

+0

इस बीच में मैंने ईएफ 4.3 असेंबली में देखा, और मुझे यह भी संदेह है कि माइग्रेशन फ्रेमवर्क कई संदर्भों का सामना कर सकता है। लेकिन कोई तकनीकी कारण नहीं है जिसके बारे में मैं सोच सकता हूं। एक ईडीएम-मॉडल के साथ आप अलग-अलग हो सकते हैं कि डेटाबेस के खिलाफ मौजूदा टेबल टेबल बनाने या बदलने और उपयोगकर्ता को मैन्युअल माइग्रेशन द्वारा हटाए गए परिदृश्य को छोड़ दें। –

उत्तर

6

कोड प्रथम माइग्रेशन मानते हैं कि प्रति डेटाबेस केवल एक माइग्रेशन कॉन्फ़िगरेशन (और प्रति कॉन्फ़िगरेशन में एक संदर्भ) है।

मैं दो संभव समाधान के बारे में सोच सकते हैं:

  1. एक समग्र संदर्भ है कि प्रत्येक संदर्भ और संदर्भ से आपके माइग्रेशन विन्यास वर्ग से इस "सुपर" संदर्भ से सभी संस्थाओं में शामिल हैं बनाएँ। इस प्रकार सभी टेबल उपयोगकर्ता के डेटाबेस में बनाए जाएंगे, लेकिन डेटा केवल उन लोगों में होगा जिनके लिए उन्होंने प्लगइन स्थापित किए हैं।

  2. प्रत्येक संदर्भ के लिए अलग डेटाबेस का उपयोग करें। यदि आपने संदर्भों के बीच इकाइयों को साझा किया है, तो एक कस्टम माइग्रेशन जोड़ें और CreateTable(...) को Sql("CREATE VIEW ...") कॉल के साथ इकाई के "मूल" डेटाबेस से डेटा प्राप्त करने के लिए कॉल करें।

मैं # 1 कोशिश करता हूं क्योंकि यह सब कुछ एक डेटाबेस में रखता है। आप अपने माइग्रेशन और यह "सुपर" संदर्भ रखने के लिए अपने समाधान में एक अलग परियोजना बना सकते हैं। बस प्रोजेक्ट जोड़ें, अपनी सभी प्लगइन्स परियोजनाओं का संदर्भ लें, एक संदर्भ बनाएं जिसमें सभी इकाइयां शामिल हों, फिर इस नई परियोजना पर सक्षम-माइग्रेशन को कॉल करें। चीजों को उसके बाद अपेक्षित काम करना चाहिए।

+5

मैं इस जवाब को स्वीकार करता हूं, भले ही यह वास्तव में मेरे प्रश्न का उत्तर न हो। मुझे लगता है कि प्रति डेटाबेस केवल एक संदर्भ में माइग्रेशन डिज़ाइन करना एक गलती है। एक तरफ प्रत्येक विरासत डेटाबेस जिसमें सारणी का उपयोग नहीं किया जाता है, संदर्भ में उपयोग नहीं किया जाता है। दूसरी तरफ (प्रीकंपिल्ड विचारों के साथ भी) लगभग 100 अलग-अलग इकाइयों वाले संदर्भ वाले ऐप डोमेन को उम्र शुरू होने में लगते हैं। इसलिए छोटे संदर्भों में विभाजित करना अभी तक एकमात्र समाधान है। –

+3

मेरा मूल उत्तर थोड़ा सा हो गया है। ईएफ 6.0 ने प्रत्येक कोड के पहले संदर्भ में एक कोड की सीमा को हटा दिया। चीजों को 6.0 और नए संस्करणों में "बस काम" करना चाहिए। – bricelam

3

मेरे पास माइग्रेशन का उपयोग करके कई संदर्भों के साथ एक कार्यशील साइट है। हालांकि, आपको प्रति संदर्भ एक अलग डेटाबेस का उपयोग करने की आवश्यकता है, और यह आपके प्रोजेक्ट के माइग्रेशन नेमस्पेस में * कॉन्फ़िगरेशन क्लास से बाहर चला गया है, उदाहरण के लिए कंपनी डीबी कॉन्टेक्स्ट कंपनी कॉन्फ़िगरेशन का उपयोग करके कंपनी.sdf को इंगित करता है। update-database -configurationtypename CompanyConfiguration। LogConfiguration, आदि का उपयोग कर Log.sdf पर एक और LogDbContext अंक

इस काम को देखते हुए, क्या आपने एक ही डेटाबेस पर इंगित 2 संदर्भ बनाने और मॉडलबिल्डर को अन्य संदर्भों की तालिका को अनदेखा करने के लिए कहने का प्रयास किया है?

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Ignore<OtherContextsClass>(); 
    // more of these 
} 

चूंकि माइग्रेशन मॉडलबिल्डर के साथ काम करते हैं, यह नौकरी कर सकता है।

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

+1

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

+0

कोई विचार अगर यह एकाधिक स्कीमा (जैसे डीबीओ) के साथ काम करेगा? – Betty

32

यहां आप क्या कर सकते हैं। बहुत आसान।

आप अपने प्रत्येक संदर्भ के लिए कॉन्फ़िगरेशन क्लास बना सकते हैं। उदाहरण

internal sealed class Configuration1 : DbMigrationsConfiguration<Context1>{ 
    public Configuration1(){ 
     AutomaticMigrationsEnabled = false; 
     MigrationsNamespace = "YourProject.Models.ContextNamespace1"; 
    } 
} 

internal sealed class Configuration2 : DbMigrationsConfiguration<Context2>{ 
    public Configuration2(){ 
     AutomaticMigrationsEnabled = false; 
     MigrationsNamespace = "YourProject.Models.ContextNamespace2"; 
    } 
} 

अब आप माइग्रेशन जोड़ते हैं। आपको माइग्रेशन को सक्षम करने की आवश्यकता नहीं है क्योंकि आपने उपरोक्त 2 वर्गों के साथ पहले से ही किया है।

Add-Migration -configuration Configuration1 Context1Init 

यह संदर्भ 1 के लिए माइग्रेशन स्क्रिप्ट बनाएगा। आप इसे अन्य संदर्भों के लिए फिर से दोहरा सकते हैं।

Add-Migration -configuration Configuration2 Context2Init 

अपने डेटाबेस

Update-Database -configuration Configuration1 
Update-Database -configuration Configuration2 

यह किसी भी क्रम में किया जा सकता है अद्यतन करने के लिए। सिवाय इसके कि आपको यह सुनिश्चित करने की आवश्यकता है कि प्रत्येक कॉन्फ़िगरेशन अनुक्रम में कहा जाता है।

+0

बिल्कुल सही, यह कहा गया है "कृपया उपयोग करने के लिए निर्दिष्ट करें" और मुझे नहीं पता था कि यह कैसे करें। धन्यवाद! – joshcomley

+1

मुझे "संदर्भ का समर्थन करने वाला मॉडल बदल गया है" जब मैं Context1 –

+2

का उपयोग करने का प्रयास करता हूं तो यह मेरे भगवान को उत्तर के रूप में चिह्नित किया जाना चाहिए !!! आपको बहुत - बहुत धन्यवाद! बस अगर मैं इसे एमवीसी 5 और ईएफ 6 – oskar132

0

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

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

1

ठीक है, अब मैं एक दिन के लिए इस के साथ संघर्ष कर दिया गया है, और यहाँ जवाब लेने वालों के लिए समाधान है ...

मैं यह सोचते हैं हूँ ज्यादातर लोगों इस पोस्ट को पढ़ने के यहाँ हैं कि क्योंकि वे एक बड़े DbContext है बहुत सारे DbSet <> गुणों के साथ वर्ग और लोड करने में लंबा समय लगता है। आपने शायद खुद को सोचा, जी, यह समझ में आता है, मुझे संदर्भ को विभाजित करना चाहिए, क्योंकि मैं एक ही समय में सभी dbsets का उपयोग नहीं करूँगा, और मैं केवल उस स्थिति के आधार पर "आंशिक" संदर्भ लोड करूंगा जहां मुझे चाहिए यह। तो आप उन्हें विभाजित करते हैं, केवल यह पता लगाने के लिए कि कोड प्रथम माइग्रेशन क्रांतिकारी सोच के आपके तरीके का समर्थन नहीं करते हैं।

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

तो फिर तुम एक के बाद हाल में अलग संदर्भों एक चल रहा करने की कोशिश की, कर ऐड-प्रवासन Context1 तो कर अद्यतन-डाटाबेस -verbose द्वारा ...

सब कुछ ठीक काम करने के लिए लग रहा था, लेकिन तब आपको लगता है कि बाद के हर नोटिस माइग्रेशन ने पिछले माइग्रेशन से सभी टेबल हटा दिए, और केवल अंतिम माइग्रेशन से टेबल को छोड़ दिया।

ऐसा इसलिए है क्योंकि वर्तमान माइग्रेशन मॉडल प्रति डाटाबेस सिंगल डीबीकॉन्टेक्स्ट की अपेक्षा करता है, और इसे दर्पण मैच होना चाहिए।

मैंने जो भी कोशिश की, और किसी ने ऐसा करने का सुझाव दिया, वह एक सुपरकॉन्टेक्स्ट बना रहा है, जिसमें सभी डीबी सेट हैं। एक माइग्रेशन कॉन्फ़िगरेशन क्लास बनाएं और इसे चलाएं। अपनी आंशिक संदर्भ कक्षाओं को जगह पर छोड़ दें, और उन्हें तुरंत इंस्टॉल करने और उनका उपयोग करने का प्रयास करें। ईएफ शिकायत करता है कि बैकिंग मॉडल बदल गया है। दोबारा, ऐसा इसलिए है क्योंकि ईएफ आपके आंशिक dbcontext को ऑल-सेट संदर्भ हस्ताक्षर से तुलना करता है जो आपके सुपर संदर्भ माइग्रेशन से छोड़ा गया था।

यह मेरी राय में एक प्रमुख दोष है।

मेरे मामले में, मैंने निर्णय लिया कि प्रवास माइग्रेशन से अधिक महत्वपूर्ण है। तो, मैं क्या कर रहा था, सुपर संदर्भ में भाग लेने के बाद और सभी तालिकाओं की जगह थी, मैं डेटाबेस में गया और मैन्युअल रूप से हटाया _MigrationHistory तालिका।

अब, मैं इसके बारे में शिकायत किए बिना अपने आंशिक संदर्भों को तत्काल और उपयोग कर सकता हूं। यह माइग्रेशन हिस्ट्री टेबल नहीं ढूंढता है और बस मुझे आगे बढ़ता है, जिससे मुझे डेटाबेस का "आंशिक" दृश्य मिल जाता है।

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

हालांकि यह मेरे लिए काम करता था।

0

निश्चित रूप से समाधान ऐसी है कि वह स्वतंत्र DbContext संस्थाओं के संशोधन संभाल कर सकते हैं _MigrationHistory_Context1 की तरह अपनी पसंद का एक तालिका नाम के _MigrationHistory तालिका के प्रत्यक्ष संशोधन का समर्थन करने के लिए एपीआई बदलने के लिए EntityFramework टीम द्वारा एक संशोधन किया जाना चाहिए। इस तरह वे सभी अलग से इलाज कर रहे हैं, और यह सुनिश्चित करने के लिए डेवलपर तक है कि इकाइयों के नाम टकरा नहीं जाते हैं।

ऐसा लगता है कि बहुत से लोग हैं जो मेरी राय साझा करते हैं कि संस्थाओं के सुपरसेट के संदर्भ में डुप्लिकेट डीबीकॉन्टेक्स्ट चीजों के बारे में जाने के लिए एक फर्जी गैर-उद्यम अनुकूल तरीका है। डुप्लिकेट डीबीकॉन्टेक्स मॉड्यूलर (प्रिज्म या इसी तरह के) आधारित समाधानों के लिए बुरी तरह विफल हो जाते हैं।

1

जैसा कि ऊपर बताया गया है, सबसे व्यावहारिक समाधान 1 सुपर डीबीकॉन्टेक्स्ट प्रति एप्लिकेशन/डेटाबेस होना है।

पूरे एप्लिकेशन के लिए केवल 1 डीबीकॉन्टेक्स्ट का उपयोग करना एक महत्वपूर्ण तकनीकी और पद्धतिपूर्ण नुकसान प्रतीत होता है, क्योंकि यह अन्य चीजों के साथ मॉड्यूलरिटी को प्रभावित करता है। साथ ही, यदि आप डब्ल्यूसीएफ डेटा सेवाओं का उपयोग कर रहे हैं, तो आप केवल प्रति डेटा 1 सेवा सेवा का उपयोग कर सकते हैं क्योंकि डेटा सेवा केवल 1 डीबीकॉन्टेक्स्ट पर मैप कर सकती है। तो यह वास्तुकला में काफी बदलाव करता है।

प्लस तरफ, एक मामूली लाभ यह है कि सभी डेटाबेस से संबंधित माइग्रेशन कोड केंद्रीकृत है।

1

मैं अभी इस समस्या से आया हूं और महसूस किया है कि मैंने उन्हें अलग-अलग संदर्भों में विभाजित करने का कारण पूरी तरह से प्रबंधनीय हिस्सों में संबंधित मॉडल का समूह बनाना था, न कि किसी अन्य तकनीकी कारण के लिए। इसके बजाय मैंने अपने संदर्भ को आंशिक वर्ग के रूप में घोषित कर दिया है और अब विभिन्न मॉडलों के साथ अलग-अलग कोड फाइलें डीबीसीएन्टेक्स्ट में डीबीसेट्स जोड़ सकती हैं।

इस तरह ऑटोमेशन जादू अभी भी काम करता है।

0

मैं लोगों को यह जानना चाहता हूं कि नीचे दिए गए उत्तर मेरे लिए क्या काम करते हैं लेकिन एक चेतावनी के साथ: माइग्रेशन नामस्थान लाइन का उपयोग न करें।

internal sealed class Configuration1 : DbMigrationsConfiguration<Context1>{ 
     public Configuration1(){ 
     AutomaticMigrationsEnabled = false; 
     MigrationsNamespace = "YourProject.Models.ContextNamespace1"; 
    } 
} 

internal sealed class Configuration2 : DbMigrationsConfiguration<Context2>{ 
    public Configuration2(){ 
     AutomaticMigrationsEnabled = false; 
     MigrationsNamespace = "YourProject.Models.ContextNamespace2"; 
    } 
} 

हालांकि, मैं पहले से ही 2 डेटाबेस परिभाषित अपने स्वयं के संदर्भों के साथ स्थापित किया था इसलिए मैं अपने आप को एक त्रुटि कह "YourProject.Models नाम स्थान पहले से ही ContextNamespace1 परिभाषित किया गया है" हो रही पाया।ऐसा इसलिए था क्योंकि "माइग्रेशंस नेमस्पेस =" YourProject.Models.ContextNamespace2 ";" IBittext के तहत dbcontext को परिभाषित किया जा रहा था। मैंने इनिट की कोशिश करने के बाद दो बार मॉडल नामस्थान (माइग्रेशन Context1Init फ़ाइल में और एक बार जहां मैंने इसे पहले परिभाषित किया था)।

तो, मैंने पाया कि मैं क्या उस बिंदु पर करना था यहाँ निर्देशों का पालन के माध्यम से अपना डेटाबेस और खरोंच से माइग्रेशन (शुक्र है मैं डेटा प्राप्त नहीं हुआ मैं रखने के लिए आवश्यक) शुरू किया गया था: तब http://pawel.sawicz.eu/entity-framework-reseting-migrations/

मैंने माइग्रेशन नेमस्पेस लाइन को शामिल करने के लिए कोड बदल दिया।

internal sealed class Configuration1 : DbMigrationsConfiguration<Context1>{ 
     public Configuration1(){ 
     AutomaticMigrationsEnabled = false; 
    } 
} 

internal sealed class Configuration2 : DbMigrationsConfiguration<Context2>{ 
    public Configuration2(){ 
     AutomaticMigrationsEnabled = false; 
    } 
} 

तब मैं ऐड-प्रवासन विन्यास कॉन्फ़िगरेशन 1 Context1Init आदेश को फिर से अद्यतन-डाटाबेस विन्यास कॉन्फ़िगरेशन 1 लाइन फिर से (मेरे 2 संदर्भ के लिए भी) भाग गया और, और अंत में, अब सब कुछ महान काम कर रहा है।

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