2016-04-30 10 views
8

मेरे पास एक एंटिटी फ्रेमवर्क कोर + एएसपी.नेट कोर एप्लिकेशन है और जब मेरा एप्लिकेशन शुरू होता है, तो मैं यह सुनिश्चित करना चाहता हूं कि डेटाबेस बनाया गया है, और अंततः (माइग्रेशन होने के बाद) मैं यह सुनिश्चित करना चाहता हूं कि वे भी चल रहे हैं।मुझे डेटाबेस कहां रखना चाहिए। सुनिश्चित करें?

शुरू में मैं अपने DbContext के निर्माता में Database.EnsureCreated() डाल लेकिन यह है कि हर बार जब कोई अपने आवेदन हिट के बाद से DbContext का एक नया उदाहरण हर बार बनाई गई है चलाने के लिए प्रकट होता है।

मैंने इसे अपने स्टार्टअप कोड में डालने की कोशिश की, लेकिन मुझे ऐसा करने के लिए मेरे DbContext का एक उदाहरण चाहिए और यह स्पष्ट नहीं है कि वास्तव में एक को कैसे प्राप्त किया जाए। मैं इतनी के रूप में एफई को विन्यस्त कर रहा हूँ:

serviceCollection.AddEntityFramework() 
    .AddSqlServer() 
    .AddDbContext<Models.MyContext>(options => options.UseSqlServer(...)); 

मैं सेवा संग्रह से DbContext का एक उदाहरण प्राप्त करने के लिए एक तरह से नहीं दिख रहा है, और मैं में तो मैं कर सकते हैं एक DbContext इंजेक्षन में सभी उचित सिंगलटन नहीं दिख रहा है कुछ एक बार प्रारंभिक करें।

तो यह सुनिश्चित करने के लिए सबसे अच्छी जगह क्या है कि मेरे डीबीकॉन्टेक्स्ट से संबंधित कुछ कोड प्रति एप्लिकेशन चलाने के लिए बुलाए जाते हैं?

+0

EnsureCreated परीक्षण के लिए है, उत्पादन के उपयोग के लिए नहीं – ErikEJ

उत्तर

3

इस लेखन के समय, आवेदन स्टार्टअप पर कोड चलाने के लिए "सही" जगह नहीं है जैसे कि यह अनुरोध क्षेत्र में निष्पादित हो (https://github.com/aspnet/Hosting/issues/373 देखें)।

अभी के लिए, वैकल्पिक हल निम्नलिखित करने के लिए है, लेकिन यह अधिक जटिल बहु आवेदन परिदृश्यों में काम नहीं करेगा (https://github.com/aspnet/EntityFramework/issues/3070#issuecomment-142752126 देख)

public class Startup 
{ 
    ... 

    public void Configure(IApplicationBuilder applicationBuilder, ...) 
    { 
     ... 
     // NOTE: this must go at the end of Configure 
     var serviceScopeFactory = applicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>() 
     using (var serviceScope = serviceScopeFactory.CreateScope()) 
     { 
      var dbContext = serviceScope.ServiceProvider.GetService<MyDbContext>(); 
      dbContext.Database.EnsureCreated(); 
     } 
    } 
} 
+0

हे माइक, मैं आपसे सहमत हूं क्योंकि मैंने यह भी देखा है कि जिथब समस्या 3070 है, लेकिन क्या आप सीधे 'MyDbContext' ** इंजेक्ट नहीं कर सकते हैं **' कॉन्फ़िगर() ' तरीका? –

+1

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

+0

बस जांच कर, मैं इस विषय पर अज्ञानता का भी दावा करता हूं :) मैंने कम से कम दो स्पॉट्स में जवाब दिया है ([उदाहरण] (https://stackoverflow.com/questions/34536021/seed-initial-data-in-entity -फ्रेमवर्क -7-आरसी -1-और-एएसपी-नेट-एमवीसी -6/44171698 # 44171698)) डीआई को सीधे कॉन्फ़िगर() में डालने का दावा है कि कैसे [परिचय दस्तावेज़] (https://docs.microsoft.com/ एन-यूएस/एस्पनेट/कोर/डेटा/एफई-एमवीसी/परिचय) ऐसा करें, शायद कोई मुझे बताएगा कि मैं गलत क्यों हूं, या वे अलग कैसे हैं। धन्यवाद, –

3

मुझे आश्चर्य है कि क्यों तुम EnsureCreated भाग के रूप में चलाने के लिए चल पाएंगे वैसे भी आपकी सेवा का। क्या आप वास्तव में चाहते हैं कि आपका वेबसर्वर डेटाबेस स्कीमा बनाएं या अपडेट करें? यदि वेबसाइवर अद्यतित नहीं है तो वेबसर्वर ऊपर उठने और अनुरोध करने का अनुरोध क्यों करेगा?

क्या आप वास्तव में अपने माइग्रेशन पर इतना भरोसा करते हैं कि निष्पादित होने पर वे डेटा को बर्बाद नहीं करते हैं, कि आप उन्हें चलाने के बाद डेटा का परीक्षण नहीं करना चाहते हैं?

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

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

+0

मैं आपके द्वारा आवेदन के भीतर से बनाने/माइग्रेट करने के खिलाफ किए गए तर्कों की सराहना करता हूं। एंटरप्राइज़ स्केल एप्लिकेशन के लिए मैं सभी बिंदुओं पर आपसे सहमत हूं। हालांकि, एक छोटी स्टार्टअप आकार की सेवा के लिए, एप्लिकेशन के अंदर बनाने/माइग्रेट करने के लिए तैनाती, परीक्षण, माइग्रेशन, प्रबंधन, डिबगिंग इत्यादि को काफी सरल बनाता है और मेरा मानना ​​है कि एमवीपी की ओर काम करते समय अतिरिक्त जोखिमों के लायक है। एक बार सेवा पर्याप्त रूप से बढ़ी है, तो कोई डीबी निर्माण/माइग्रेशन निकालने में देख सकता है। –

+0

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

+0

एक अच्छी 'माइग्रेट' उपयोगिता है जो यह करता है। – zmbq

0

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

जब एक आईआईएस उदाहरण के खिलाफ प्रकाशित करने, एक भी आवश्यक माइग्रेशन चलाने के लिए उपयोग करने के लिए लक्ष्य डेटाबेस कनेक्शन स्ट्रिंग निर्दिष्ट कर सकते हैं:

Entity framework migrations used when publishing

यह सुनिश्चित होगा कि परिवर्तन केवल जब जरूरत लागू होते हैं (नहीं हर बार आवेदन शुरू होता है) और वह एप्लिकेशन कम से कम आवश्यक डेटाबेस अधिकारों (यानी डेटाबेस लेखक, पाठक इत्यादि) का उपयोग करके चलाता है क्योंकि तालिकाओं को बदलने, इंडेक्स आदि बनाने के अधिकारों के विपरीत।

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