इकाई फ्रेमवर्क रोलबैक और खराब प्रवासन को हटा दें


174

मैं मैनुअल माइग्रेशन और अपडेट के साथ C # में अपनी परियोजना के लिए EF 6.0 का उपयोग कर रहा हूं। मेरे पास डेटाबेस पर लगभग 5 माइग्रेशन हैं, लेकिन मुझे एहसास हुआ कि अंतिम प्रवास खराब था और मैं यह नहीं चाहता। मुझे पता है कि मैं पिछले माइग्रेशन में रोलबैक कर सकता हूं, लेकिन जब मैं एक नया (फिक्स्ड) माइग्रेशन जोड़ता हूं और अपडेट-डेटाबेस चलाता हूं, तो भी खराब माइग्रेशन लागू होता है।

मैं पिछले माइग्रेशन को रोलबैक करने और फ़ाइल को खराब माइग्रेशन से हटाने का प्रयास कर रहा था। लेकिन फिर, जब मैं नया माइग्रेशन जोड़ने का प्रयास करता हूं, तो डेटाबेस अपडेट करते समय मुझे त्रुटि मिलती है, क्योंकि माइग्रेशन फ़ाइल दूषित है (अधिक विशेष रूप से, कोड की पहली पंक्ति ए से बी तक तालिका का नाम बदल देती है और अगली लाइनें है, ईएफ तालिका को अपडेट करने की कोशिश कर रहा है। नाम A - शायद यह कुछ EF बग है)।

क्या मेरे द्वारा चलाए जा सकने वाली कुछ क्वेरी है, जो EF को कुछ ऐसा बताएगी जैसे "पिछले प्रवास को भूल जाओ जैसे यह कभी अस्तित्व में नहीं था, यह बुरा था"? निकालें-प्रवासन जैसा कुछ।

Edit1 मुझे मेरे लिए अनुकूल समाधान मिला। मॉडल को अच्छे राज्य में बदलना और चलाना Add-Migration TheBadMigration -Force। यह लागू किए गए माइग्रेशन को अंतिम रूप से पुन: मचान बना देगा।

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

धन्यवाद


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

जवाबों:


167

आपके पास 2 विकल्प हैं:

  • आप खराब माइग्रेशन से डाउन ले सकते हैं और इसे नए माइग्रेशन में डाल सकते हैं (आपको मॉडल के बाद के बदलाव करने की भी आवश्यकता होगी)। यह प्रभावी रूप से एक बेहतर संस्करण के लिए चल रहा है।

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

  • दूसरा विकल्प वास्तव Update-Database –TargetMigration: TheLastGoodMigrationमें आपके तैनात डेटाबेस के खिलाफ है और फिर आपके समाधान से माइग्रेशन को हटा दें। यह थोथा स्मैश विकल्प है और इसे खराब संस्करण के साथ तैनात किसी भी डेटाबेस के खिलाफ प्रदर्शन करने की आवश्यकता है।

    नोट: आपके द्वारा उपयोग किए जा सकने वाले माइग्रेशन को पुनर्विक्रय करने के लिए Add-Migration [existingname] -Force। हालाँकि यह आपके मौजूदा माइग्रेशन को अधिलेखित कर देगा, इसलिए ऐसा तभी करें जब आपने डेटाबेस से मौजूदा माइग्रेशन को हटा दिया हो। यह मौजूदा माइग्रेशन फ़ाइल को हटाने और चलाने के समान काम करता हैadd-migration

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


1
हल्क स्मैश विकल्प काम नहीं करता है। मैंने अभी तक डेटाबेस में खराब माइग्रेशन लागू नहीं किया था। मैंने कोशिश की, लेकिन यह काम नहीं कर रहा था, क्योंकि तालिका नाम मैंने मूल प्रश्न में निर्दिष्ट किया था। पहला विकल्प मुझे ज्यादा पसंद नहीं है, क्योंकि ऐसा लगता है कि मुझे माइग्रेशन का कोड बदलना होगा। अगर मैं इसे खराब करता हूं, तो मैं इसे पूरी तरह से तोड़ सकता हूं।
मार्टिन Brabec

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

4
'हल्क तोड़' जवाब है, यह मेरे लिए काम करता है जब मैं विकसित हो रहा हूं और मैं अपने द्वारा किए गए प्रवासन में कुछ जोड़ना चाहता हूं। मुझे लगता है कि मार्टिन के लिए काम नहीं करने के कारण असंबंधित हैं (या संभवतः डेटाबेस स्कीमा को मैन्युअल रूप से बदलने से संबंधित हैं)
rethenhouser2

1
@BenRethmeier एक सामान्य नियम के रूप में मैं केवल विकसित होते समय hulk smash विकल्प का उपयोग करता हूं। ठेस में मैं हमेशा समस्या को ठीक करने के लिए एक नया प्रवासन बनाता हूं। कारण यह है कि यदि आप डेटाबेस को अपग्रेड कर रहे हैं तो आपको मैन्युअल हस्तक्षेप की आवश्यकता है। मुझे ऐसी कोई भी चीज़ पसंद नहीं है जिसे प्रोड्यूस में मैन्युअल हस्तक्षेप की आवश्यकता हो।
प्यार नहीं किया

1
HULK SMASH !!!! --- मैंने अच्छा होने की कोशिश की लेकिन EF नहीं खेल रहा था - मैं पिछले ज्ञात पर वापस लौट आया - (बैकअप फ़ाइलों को माइग्रेट किया गया) हटा दिया गया, माइग्रेशन जोड़ा गया - Force - पिछले पर आ गया और कोड की प्रतिलिपि बना दी गई। अद्यतन करें फिर जोड़ा गया दूसरी तरह से प्रवास - कोई त्रुटि नहीं - वापस सामान्य
ट्रैसी

127

जैसा कि प्रश्न इंगित करता है कि यह एक विकास प्रकार के वातावरण में प्रवास पर लागू होता है जो अभी तक जारी नहीं किया गया है।

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

चरण 1: पिछले माइग्रेशन को पुनर्स्थापित करें

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

Update-Database TargetMigration: <name of last good migration>

अंतिम अच्छे माइग्रेशन का नाम पाने के लिए अपने डेटाबेस पर लागू किए गए माइग्रेशन नामों की सूची को पुनः प्राप्त करने के लिए 'गेट-माइग्रेशन' कमांड का उपयोग करें।

PM> Get-Migrations
Retrieving migrations that have been applied to the target database.
201508242303096_Bad_Migration
201508211842590_The_Migration_applied_before_it
201508211440252_And_another

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

Update-Database TargetMigration: "<the migration applied before it>"

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

चरण 2: प्रोजेक्ट से अपना माइग्रेशन हटाएं

remove-migration name_of_bad_migration

यदि remove-migrationकमांड आपके एंटिटी फ्रेमवर्क के संस्करण में उपलब्ध नहीं है, तो अपने ईएफ प्रोजेक्ट 'माइग्रेशन' फ़ोल्डर के अनचाहे माइग्रेशन की फ़ाइलों को मैन्युअल रूप से हटा दें। इस बिंदु पर, आप एक नया माइग्रेशन बनाने और डेटाबेस पर लागू करने के लिए स्वतंत्र हैं।

चरण 3: अपना नया माइग्रेशन जोड़ें

add-migration my_new_migration

चरण 4: डेटाबेस में अपना माइग्रेशन लागू करें

update-database

6
ईएफ कोर के साथ ऐसा लगता है कि गेट-माइग्रेशन हटा दिया गया है।
केविन बर्टन

1
चरण 2 ! - बहुत उपयोगी सुविधा। जैसा @KevinBurton ने उल्लेख किया है। और फिर add-migration "new migration",update-database
अलेक्जेंडर फ्रोलोव

2
अद्यतन-डाटाबेस -migration: "<प्रवास यह पहले लागू>" @ दाऊद Sopko
Fuat

धन्यवाद @AlexanderFrolov मैंने आपकी टिप्पणियों को प्रतिबिंबित करने के लिए समाधान अपडेट किया।
डेविड सोपको

1
हमें चरण 2 के बाद हटाने-माइग्रेशन का उपयोग करने की आवश्यकता है
राहुल

55

ASP.NET Core v1.0.0 के साथ EF Core का उपयोग करने वालों के लिए मेरे पास एक समान समस्या थी और इसे ठीक करने के लिए निम्न आदेशों का उपयोग किया (@ DavidSopko की पोस्ट ने मुझे सही दिशा में इंगित किया, लेकिन विवरण EF Core के लिए थोड़ा अलग हैं) :

Update-Database <Name of last good migration>
Remove-Migration

उदाहरण के लिए, मेरे वर्तमान विकास में कमांड बन गया

PM> Update-Database CreateInitialDatabase
Done.
PM> Remove-Migration
Done.
PM> 

आपके द्वारा लागू अंतिम माइग्रेशन को निकालें-माइग्रेशन निकाल देगा। यदि आपके पास हटाने के लिए कई माइग्रेशन के साथ अधिक जटिल परिदृश्य है (मेरे पास केवल 2, प्रारंभिक और खराब एक है), तो मेरा सुझाव है कि आप एक डमी परियोजना में चरणों का परीक्षण करें।

वर्तमान में EF Core (v1.0.0) में गेट-माइग्रेशन कमांड प्रतीत नहीं होता है, इसलिए आपको अपने माइग्रेशन फ़ोल्डर में देखना होगा और जो आपने किया है उससे परिचित होना चाहिए। हालाँकि, एक अच्छी मदद कमांड है:

PM> get-help entityframework

VS2015 SQL सर्वर ऑब्जेक्ट एक्स्प्लोरर में dastabase को ताज़ा करते हुए, मेरे सभी डेटा को संरक्षित किया गया था और जिस माइग्रेशन को मैं फिर से लिखना चाहता था वह था :)

प्रारंभ में मैंने स्वयं ही निकालें-माइग्रेशन का प्रयास किया और त्रुटि कमांड को भ्रामक पाया:

System.InvalidOperationException: माइग्रेशन '...' पहले ही डेटाबेस पर लागू हो चुका है। इसे अनप्लग करें और फिर से प्रयास करें। यदि माइग्रेशन अन्य डेटाबेस पर लागू किया गया है, तो नए माइग्रेशन का उपयोग करके इसके परिवर्तनों को वापस करने पर विचार करें।

इस शब्द को बेहतर बनाने पर पहले से ही सुझाव हैं, लेकिन मैं इस तरह से कुछ कहना त्रुटि चाहूंगा:

डेटाबेस स्कीमा को उस स्थिति में वापस लाने के लिए अद्यतन-डेटाबेस (अंतिम अच्छा माइग्रेशन नाम) चलाएँ। यह आदेश अद्यतन-डेटाबेस के लिए निर्दिष्ट माइग्रेशन के बाद हुए सभी माइग्रेशनों को अनपेक्षित रूप से अनप्लग कर देगा। फिर आप निकालें-माइग्रेशन (माइग्रेशन नाम को निकालने के लिए) चला सकते हैं

EF कोर मदद कमांड से आउटपुट निम्नानुसार है:

 PM> get-help entityframework
                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\

TOPIC
    about_EntityFrameworkCore

SHORT DESCRIPTION
    Provides information about Entity Framework Core commands.

LONG DESCRIPTION
    This topic describes the Entity Framework Core commands. See https://docs.efproject.net for information on Entity Framework Core.

    The following Entity Framework cmdlets are included.

        Cmdlet                      Description
        --------------------------  ---------------------------------------------------
        Add-Migration               Adds a new migration.

        Remove-Migration            Removes the last migration.

        Scaffold-DbContext          Scaffolds a DbContext and entity type classes for a specified database.

        Script-Migration            Generates a SQL script from migrations.

        Update-Database             Updates the database to a specified migration.

        Use-DbContext               Sets the default DbContext to use.

SEE ALSO
    Add-Migration
    Remove-Migration
    Scaffold-DbContext
    Script-Migration
    Update-Database
    Use-DbContext

6

आप भी उपयोग कर सकते हैं

Remove-Migration -Force

यह अंतिम लागू माइग्रेशन को वापस ले जाएगा और हटा देगा


4

सबसे पहले, इस कमांड के माध्यम से अपना अंतिम सही माइग्रेशन अपडेट करें:

Update-Database TargetMigration

उदाहरण:

Update-Database -20180906131107_xxxx_xxxx

और, फिर अपने अप्रयुक्त माइग्रेशन को मैन्युअल रूप से हटा दें।


2
यह होना चाहिए: अपडेट-डेटाबेस -टार्गेट माइग्रेशन 20180906131107_xxxx_xxxx
Elger Mensonides

Update-Database 20180906131107_xxxx_xxxx(कोई हाइफ़न) ने मेरे लिए काम नहीं किया। TargetMigrationस्विच के रूप में किसी भी संस्करण ने काम नहीं किया। ये कमांड एक चलते लक्ष्य के रूप में प्रतीत होते हैं (अर्थात हर संस्करण में इन्हें बदलें)?
सूमो कोई नहीं

3

.NET कोर 2.2 के अनुसार, TargetMigrationलगता है:

get-help Update-Database

NAME
    Update-Database

SYNOPSIS
    Updates the database to a specified migration.


SYNTAX
    Update-Database [[-Migration] <String>] [-Context <String>] [-Project <String>] [-StartupProject <String>] [<CommonParameters>]


DESCRIPTION
    Updates the database to a specified migration.


RELATED LINKS
    Script-Migration
    about_EntityFrameworkCore 

REMARKS
    To see the examples, type: "get-help Update-Database -examples".
    For more information, type: "get-help Update-Database -detailed".
    For technical information, type: "get-help Update-Database -full".
    For online help, type: "get-help Update-Database -online"

तो यह मेरे लिए अब काम करता है:

Update-Database -Migration 20180906131107_xxxx_xxxx

साथ ही (कोई -Migrationस्विच नहीं ):

Update-Database 20180906131107_xxxx_xxxx

एक जोड़ा नोट पर, आप अपने मॉडल स्नैपशॉट को सिंक से बाहर निकाले बिना माइग्रेशन फ़ोल्डरों को आसानी से हटा नहीं सकते। इसलिए यदि आप इसे कठिन तरीके से सीखते हैं और एक खाली माइग्रेशन के साथ हवा करते हैं, जहां आपको पता है कि बदलाव होने चाहिए, तो आप चला सकते हैं (अंतिम प्रवास के लिए आवश्यक कोई स्विच नहीं):

Remove-migration

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


0

ईएफ 6 के लिए यहां एक-लाइनर है यदि आप विकास में बहुत अधिक फेरबदल कर रहे हैं। बस var को अपडेट करें और फिर पैकेज मैनेजर कंसोल में अप एरो का उपयोग करके कुल्ला और दोहराएं।

$lastGoodTarget = "OldTargetName"; $newTarget = "NewTargetName"; Update-Database -TargetMigration "$lastGoodTarget" -Verbose; Add-Migration "$newTarget" -Verbose -Force

यह आवश्यक क्यों है आप पूछें? निश्चित नहीं है कि यह EF6 के किन संस्करणों पर लागू होता है, लेकिन यदि आपका नया माइग्रेशन लक्ष्य पहले ही लागू हो चुका है, तो ऐड-माइग्रेशन में फिर से पाड़ करने के लिए '-Force' का उपयोग करके वास्तव में री-मचान नहीं बनाया जाएगा, बल्कि एक नई फ़ाइल बनाएं (यह एक अच्छी बात है) हालाँकि, क्योंकि आप अपना 'डाउन' नहीं खोना चाहते)। उपरोक्त स्निपेट पहले 'डाउन' करता है यदि आवश्यक हो तो -फिर फिर से मचान पर ठीक से काम करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.