ऑटो एंटिटी फ्रेमवर्क कोर में डेटाबेस बनाते हैं


100

मेरा अनुप्रयोग जो .NET कोर में पोर्ट किया जा रहा है, SQLite के साथ नए EF Core का उपयोग करेगा। जब ऐप पहले चलाया जाता है तो मैं डेटाबेस और टेबल संरचनाओं को स्वचालित रूप से बनाना चाहता हूं। ईएफ कोर प्रलेखन के अनुसार यह मैनुअल कमांड का उपयोग करके किया जाता है

dotnet ef migrations add MyFirstMigration

dotnet ef database update

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

Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>());

लेकिन EF Core में ये मौजूद नहीं हैं। मुझे EF कोर के समकक्ष कुछ उदाहरण या दस्तावेज नहीं मिल सकते हैं और इसका उल्लेख EF कोर प्रलेखन में अनुपलब्ध सुविधाओं की सूची में नहीं है। मेरे पास पहले से ही मॉडल कक्षाएं हैं, इसलिए मैं मॉडल के आधार पर डेटाबेस को इनिशियलाइज़ करने के लिए कुछ कोड लिख सकता हूं लेकिन यह आसान होगा अगर फ्रेमवर्क ने यह स्वचालित रूप से किया। मैं मॉडल का निर्माण या माइग्रेट करना नहीं चाहता, बस एक नए डेटाबेस पर तालिका संरचनाएं बनाता हूं।

क्या मुझे यहाँ कुछ याद आ रहा है या EF कोर में ऑटो फंक्शन टेबल गायब है?

जवाबों:


146

यदि आपने माइग्रेशन बनाए हैं, तो आप निम्नानुसार उन्हें Startup.cs में निष्पादित कर सकते हैं।

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.Migrate();
      }

      ...

यह आपके अतिरिक्त माइग्रेशन का उपयोग करके डेटाबेस और तालिकाओं का निर्माण करेगा।

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

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.EnsureCreated();
      }

      ...

बजाय।

यदि आपको यह सुनिश्चित करने से पहले अपने डेटाबेस को हटाने की आवश्यकता है कि यह बनाया गया है, तो कॉल करें:

            context.Database.EnsureDeleted();

पुकारने से ठीक पहले EnsureCreated()

से अनुकूलित: http://docs.identityserver.io/en/latest/quickstarts/7_entity_framework.html?highlight=entity


1
मैं अभी भी EF के लिए बहुत नया हूँ, मैंने एक मौजूदा डेटाबेस फ़ाइल का उपयोग करके विज़ुअल स्टूडियो से "पहले डेटाबेस से बनाएं" EF 6 कोड का उपयोग करके डेटा संरचनाओं को परिभाषित करने वाली कक्षाएं बनाईं। फिर मैंने उन्हें नए डॉटनेट कोर वीएस समाधान में काट / चिपकाया - इसलिए मुझे लगता है कि ये पलायन नहीं हैं। क्या इसका मतलब है कि उपरोक्त कोड का उपयोग करने से पहले मुझे एक माइग्रेशन फ़ाइल बनानी होगी?
डेन्डबोब

2
मैं `माफ करना, मैं एक गलती मेरा उत्तर में, किया था अगर आप माइग्रेशन का उपयोग नहीं कर रहे हैं, आदेश context.Database.EnsureCreated () / EnsureDeleted (), में अधिक जानकारी के लिए उपयोग कर सकते blogs.msdn.microsoft.com/dotnet/2016 / 09/29 /…
रिकार्डो फोंटाना

2
यदि आपको दोनों समाधानों की आवश्यकता हो तो क्या होगा? हमने अभी अपने ऐप को UWP में पोर्ट कर लिया है और EF Core का उपयोग करना शुरू कर दिया है, जिसका अर्थ है कि कुछ उपयोगकर्ताओं को स्क्रैच से डीबी बनाने की आवश्यकता है, जबकि अन्य के पास पहले से ही डीबी है। क्या यह सुनिश्चित करने का कोई तरीका है कि पहला प्रवास केवल प्रारंभिक तालिकाओं को बनाता है यदि वे पहले से मौजूद नहीं हैं? आपका उत्तर यह कवर नहीं करता है या मैं कुछ याद कर रहा हूँ?
लार्स उदेंगार्ड

33

मेरा जवाब रिकार्डो के जवाब से काफी मिलता-जुलता है, लेकिन मुझे लगता है कि मेरा दृष्टिकोण थोड़ा और सरल है, क्योंकि उसके usingकार्य में इतना कुछ चल रहा है कि मुझे यकीन भी नहीं हो रहा है कि यह वास्तव में निचले स्तर पर कैसे काम करता है।

तो उन लोगों के लिए जो एक सरल और साफ समाधान चाहते हैं जो आपके लिए एक डेटाबेस बनाता है जहां आप जानते हैं कि वास्तव में हुड के नीचे क्या हो रहा है, यह आपके लिए है:

public Startup(IHostingEnvironment env)
{
    using (var client = new TargetsContext())
    {
        client.Database.EnsureCreated();
    }
}

इसका बहुत मतलब यह है DbContextकि आपके द्वारा बनाए गए (इस मामले में, मेरा कहा जाता है TargetsContext), आप DbContextयह सुनिश्चित करने के लिए एक उदाहरण का उपयोग कर सकते हैं कि जब आपके आवेदन में Startup.cs चलाया जाता है , तो कक्षा में परिभाषित टेबल बनाए जाते हैं ।


10
बस यहां से एक जानकारी के रूप में : EnsureCreatedपूरी तरह से पलायन को रोक देता है और बस आपके लिए स्कीमा बनाता है, आप इसे माइग्रेशन के साथ नहीं मिला सकते हैं। EnsureCreatedपरीक्षण या तेजी से प्रोटोटाइप के लिए डिज़ाइन किया गया है जहां आप हर बार डेटाबेस को छोड़ने और फिर से बनाने के साथ ठीक हैं। यदि आप माइग्रेशन का उपयोग कर रहे हैं और चाहते हैं कि वे स्वचालित रूप से ऐप स्टार्ट पर लागू हों, तो आप context.Database.Migrate()इसके बजाय उपयोग कर सकते हैं ।
थॉमस श्नाइटर

यह मेरी उलझन का जवाब देता है कि मेरा कनेक्शन स्ट्रिंग क्यों काम नहीं कर रहा है ... :( इसलिए डेटाबेस ने स्वचालित रूप से नहीं बनाया है कि आपको डेटाबेस निर्दिष्ट करना होगा। ईन्सेचरक्रिएटेड () जो मैंने अपने DbContext कंस्ट्रक्टर में किया था। बहुत बहुत धन्यवाद, 3 दिनों की दुविधा से मुझे बचाता है। X_X
पम्पी

बस यह नोट करना चाहता था कि मैंने अपनी स्टार्टअप फ़ाइल में इसे चिपकाने की कोशिश की और VS2019 ने मुझे सूचित किया कि IHostingEnvironmentअब पदावनत कर दिया गया है और अनुशंसित विकल्प है Microsoft.AspNetCore.Hosting.IWebHostEnvironment
सीटीटी-जेड pls

18

यदि आप Startup.cs में कॉन्फ़िगर की पैरामीटर सूची के माध्यम से संदर्भ प्राप्त करते हैं, तो आप इसके बजाय यह कर सकते हैं:

public void Configure(IApplicationBuilder app, IHostingEnvironment env,  LoggerFactory loggerFactory,
    ApplicationDbContext context)
 {
      context.Database.Migrate();
      ...

1
IMHO यह सबसे अच्छा समाधान है: आपको किसी भी सेवा या यहां तक ​​कि DB संदर्भ की परवाह करने की ज़रूरत नहीं है, आप बस उस संदर्भ का उपयोग कर सकते हैं जो आपको निर्भरता इंजेक्शन के माध्यम से मिलता है। अच्छा!
टोबियास

13

ईएफ कोर 2.0+ के लिए मुझे एक अलग दृष्टिकोण लेना पड़ा क्योंकि उन्होंने एपीआई को बदल दिया। मार्च 2019 तक Microsoft अनुशंसा करता है कि आप अपना डेटाबेस माइग्रेशन कोड अपने एप्लिकेशन एंट्री क्लास में डाल सकते हैं लेकिन WebHost बिल्ड कोड के बाहर।

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var serviceScope = host.Services.CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<PersonContext>();
            context.Database.Migrate();
        }
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

7

यदि आपने माइग्रेशन नहीं बनाया है, तो 2 विकल्प हैं

1. आवेदन से डेटाबेस और तालिकाओं का निर्माण करें:

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();

2. तालिकाएँ बनाएँ यदि डेटाबेस पहले से मौजूद है:

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();
RelationalDatabaseCreator databaseCreator =
(RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();

बबी के जवाब के लिए धन्यवाद


2
आपकी सेवाएं क्या है?
माइकलमो

सभी प्रलेखन मैं कह "का प्रयोग न करें माइग्रेशन चारों ओर से पता चलता है पढ़ रहा हूँ बिग फैट चेतावनी EnsureCreatedया EnsureDeletedया Database.Migrateअसफल हो जायेगी"
mwilson
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.