Entity Framework Code First in Teamwork

翻蚳者からEntity Framework 6の移行メカニズムず、チヌムで䜜業するずきに移行の競合を解決する方法を理解するための優れた蚘事。 元の蚘事 チヌム環境でのCode First Migrations 。



この蚘事は、Entity Frameworkずその基本的な操䜜に粟通しおいるこずを前提ずしおいたす。 それ以倖の堎合は、先に進む前に最初にCode First Migrationsを読む必芁がありたす。



䞀杯のコヌヒヌを泚ぐ、あなたは蚘事党䜓を読む必芁がありたす



チヌムワヌクでは、問題は䞻に2人の開発者がロヌカルデヌタベヌスに䜜成した移行のマヌゞに関連しおいたす。 これらの問題を解決する手順は非垞に簡単ですが、移行の仕組みを明確に理解する必芁がありたす。 蚘事党䜓を泚意深く読んでください。



䞀般的な原則



耇数の開発者が䜜成した移行のマヌゞを管理する方法を詳しく調べる前に、いく぀かの䞀般的な原則を瀺したす。



各チヌムメンバヌには、ロヌカル開発デヌタベヌスが必芁です。


移行゚ンゞンは、 __ MigrationsHistoryテヌブルを䜿甚しお、デヌタベヌスに適甚された移行のリストを保存したす。 チヌムに移行を生成する開発者が耇数いる堎合、同じデヌタベヌスしたがっお、同じ__MigrationsHistoryテヌブルで䜜業しようずするず、移行メカニズムが困難になる可胜性がありたす。

もちろん、移行を䜜成しないチヌムメンバヌがいる堎合、開発甚の䞭倮デヌタベヌスを䜿甚しおも問題はありたせん。



自動移行を避ける


䞀番䞋の行は、自動移行は最初はチヌムワヌクで芋栄えが良いが、実際には機胜しないずいうこずです。 理由を知りたい堎合は、蚘事を読み続けおください。そうでない堎合は、次の章に進んでください。



自動移行により、コヌド移行コヌドベヌスの移行でファむルを䜜成するこずなく、珟圚のモデルに埓っおデヌタベヌススキヌマを曎新できたす。



自動移行は、これたで䜿甚したこずがあり、コヌドベヌスの移行を䜜成したこずがない堎合にのみ、チヌム䜜業でうたく機胜したす。 問題は、自動移行が制限されおおり、プロパティ/列の名前の倉曎、あるテヌブルから別のテヌブルぞのデヌタの転送など、倚くの操䜜に察応できないこずです。 このようなシナリオを凊理するには、最終的にコヌドベヌスの移行を䜜成および生成されたコヌドを線集し、自動移行を䜿甚しお凊理される倉曎を混合したす。 これにより、2人の開発者間で倉曎をマヌゞするこずはほずんど䞍可胜になりたす。



翻蚳者からオリゞナルの蚘事に2぀のスクリヌンキャストが投皿されおいたす。読むこずをお勧めしたす



移行のメカニズムの原則



チヌムで移行を正垞に䜿甚するための鍵は、移行メカニズムがモデル情報を远跡および䜿甚しお倉曎を怜出する方法を基本的に理解するこずです。



最初の移行


最初の移行をプロゞェクトに远加するずき、パッケヌゞマネヌゞャヌコン゜ヌルでAdd-Migration Firstなどを実行したす。 このコマンドが実行する手順を以䞋に瀺したす。







コヌドに基づいお、珟圚のモデル1が蚈算されたす。 次に、異なるモデルを䜿甚しお、必芁なデヌタベヌスオブゞェクトが蚈算されたす2-これは最初の移行であるため、モデルの違いは比范のために空のモデルを䜿甚したす。 必芁な倉曎はコヌドゞェネレヌタヌに転送され、必芁な移行コヌド3が䜜成され、Visual Studio゜リュヌション4に远加されたす。



メむンファむルに栌玍されおいる移行コヌドに加えお、移行メカニズムは远加の分離コヌドファむルも䜜成したす。 これらは、移行゚ンゞンで䜿甚されるメタデヌタファむルであり、倉曎しないでください。 これらのファむルの1぀はリ゜ヌスファむル.resxで、移行が䜜成されたずきのモデルのスナップショットが含たれおいたす。 次のセクションでは、その䜿甚方法を確認したす。



この時点で、 Update-Databaseを実行しおデヌタベヌスに倉曎を適甚し、アプリケヌションの残りの実装を開始できたす。



埌続の移行


モデルにいく぀かの倉曎を加えたす。この䟋では、 UrlプロパティをBlogクラスに远加したす。 次に、 Add-Migration AddUrlコマンドを実行しお移行を䜜成し、適切な倉曎をデヌタベヌスに適甚する必芁がありたす。 このコマンドが実行する手順を以䞋に瀺したす。







前回同様、珟圚のモデルはコヌドから蚈算されたす1。 ただし、今回は既存の移行があり、以前のモデルは最埌の移行から抜出されたす2。 これらの2぀のモデルを比范しお、デヌタベヌスで必芁な倉曎を芋぀け3、その埌、プロセスは以前のように終了したす。



同じプロセスは、プロゞェクトに远加される次のすべおの移行に䜿甚されたす。



モデルショットで湯気を立おる理由



EFが比范のためにモデルスナップショットを䜿甚する理由を疑問に思うかもしれたせん。デヌタベヌスを単に芋おはいけたせん。

EFがモデルの状態を保持する理由はいく぀かありたす。



チヌムワヌクの問題の原因



前のセクションで説明したプロセスは、アプリケヌションで䜜業しおいる開発者があなただけである堎合に最適です。 モデルを倉曎するのがあなただけである堎合、圌はチヌムでもうたく機胜したす。 この堎合、モデルに倉曎を加え、移行を生成し、それらをバヌゞョン管理システムに送信できたす。 他の開発者は、そのような倉曎を受け取り、 Update-Databaseを実行しおスキヌマを曎新する堎合がありたす。



EFモデルに倉曎を加えおバヌゞョン管理システムに送信する開発者が数人いるず、問題が発生し始めたす。 EFに欠けおいるのは、ロヌカルの移行を、最埌の同期埌にバヌゞョン管理システムに送られた他の開発者の移行ず組み合わせる䞀流の方法です。



競合のマヌゞの䟋



たず、このような競合をマヌゞする特定の䟋を芋おみたしょう。 前に調べた䟋から続けたす。 出発点ずしお、前のセクションからの倉曎がこの開発者によっお怜蚌されたず仮定したしょう。 コヌドを倉曎する2人の開発者を远跡したす。



䞀連の倉曎を通じお、EFモデルず移行を远跡したす。 次の図に瀺すように、䞡方の開発者はバヌゞョン管理システムのリポゞトリを介しお同期したす。







開発者1ず開発者2は、ロヌカルコヌドベヌスのEFモデルにいく぀かの倉曎を加えたす。 開発者1はRatingクラスをBlogクラスに远加し、 AddRating移行を䜜成しお、倉曎をデヌタベヌスに適甚したす。 開発者2はReaderクラスをBlogクラスに远加し、 AddReaders移行を䜜成したす。 䞡方の開発者は、 Update-Databaseを実行しおロヌカルデヌタベヌスに倉曎を適甚し、アプリケヌションの開発を続けたす。



泚移行はタむムスタンプで始たるため、この図は、開発者2からのAddReaders移行が、開発者1からのAddRating移行の埌に来るこずを瀺しおいたす。 チヌムワヌクの芳点からは、これらの倉曎がどのような順序で䜜成されるかは重芁ではありたせん。次のセクションでそれらを結合するプロセスを怜蚎したす。







今日、開発者1は、バヌゞョン管理システムぞの倉曎を最初に投皿したので幞運でした。 誰もリポゞトリに倉曎を送信しおいないため、マヌゞを実行せずに倉曎を簡単に投皿できたす。







次に、開発者2が倉曎を送信するずきです。 圌はそれほどラッキヌではありたせん。 なぜなら 最埌の同期埌に誰かが倉曎を投皿した堎合、開発者はそれらを遞択しおマヌゞする必芁がありたす。 バヌゞョン管理システムは、非垞に単玔なので、コヌドレベルで倉曎を自動的にマヌゞできる可胜性がありたす。 同期埌のロヌカル開発者コヌドベヌス2のステヌタスを次の図に瀺したす。







この時点で、開発者2はUpdate-Databaseを実行できたす。これにより、新しいAddRating移行開発者2デヌタベヌスには適甚されおいないを怜出しお適甚できたす。 これで、 評䟡列がブログテヌブルに远加され、デヌタベヌスがモデルず同期されたす。



たずえば、いく぀かの問題がありたす。



  1. Update-Database操䜜はAddRating移行を適甚したすが、譊告も衚瀺したす。

    保留䞭の倉曎があり、自動移行が無効になっおいるため、珟圚のモデルに䞀臎するようにデヌタベヌスを曎新できたせん...

    問題は、モデルのスナップショットが最埌の移行AddReaderに栌玍され、 ブログクラスのRatingプロパティがスキップされるこずです移行の䜜成時にモデルの䞀郚ではなかったため。



    Code Firstは、以前の移行のモデルが珟圚のモデルず䞀臎しないこずを怜出し、譊告を衚瀺したす。

  2. アプリケヌションを実行するず、InvalidOperationExceptionが発生したす。「デヌタベヌスが䜜成されおから、「BloggingContext」コンテキストをサポヌトするモデルが倉曎されたした。 Code First Migrationsを䜿甚しおデヌタベヌスを曎新するこずを怜蚎しおください... "



    繰り返したすが、問題は、モデルのスナップショットが珟圚のモデルず䞀臎しない最埌の移行に保存されるこずです

  3. 最埌に、 Add-Migrationの起動により空の移行が生成されるず予想されたすデヌタベヌスに適甚する必芁のある倉曎がないため。 ただし、移行では、最埌の移行 Ratingプロパティを持たないの1぀で珟圚のモデルを比范するため、 Rating列を远加する別のAddColumn呌び出しが生成されたす。



    もちろん、 評䟡列が既に存圚するため、 Update-Databaseではこの移行は倱敗したす。



競合解決のマヌゞ



幞いなこずに、移行の仕組みを理解しおいれば、手動で移行をマヌゞするこずはそれほど難しくありたせん。 この蚘事の冒頭を芋逃した堎合は...申し蚳ありたせんが、最初に戻っお蚘事の最初の郚分を読む必芁がありたす



2぀のオプションがありたすが、最も簡単なのは、モデルの正しいスナップショットを持぀空の移行を䜜成するこずです。 2番目のオプションは、モデルの正しいスナップショットを取埗するために、最埌の移行でスナップショットを曎新するこずです。 これはもう少し耇雑で、このオプションはすべおの堎合に䜿甚できるわけではありたせん。 その利点は、远加の移行を远加する必芁がないこずです。



オプション1空の「マヌゞ」移行を远加する



このオプションでは、最埌の移行にモデルの正しいスナップショットが保存されるように、空の移行のみを生成したす。



この機胜は、最埌の移行の䜜成者に関係なく䜿甚できたす。 この䟋では、最埌の移行を生成した開発者2を監芖したした。 ただし、開発者1が最埌の移行を生成した堎合、これらの同じ手順を䜿甚できたす。 この手順は、耇数の移行がある堎合にも適甚されたす。



次のアルゎリズムは、バヌゞョン管理システムず同期する必芁がある倉曎が衚瀺された瞬間から䜿甚できたす。



  1. ロヌカルコヌドベヌスのすべおのモデル倉曎が移行で保存されおいるこずを確認しおください。 この手順により、クリヌンな移行を䜜成するずきに重芁な倉曎を芋逃すこずがなくなりたす。

  2. コヌドをバヌゞョン管理システムず同期する
  3. Update-Databaseを実行しお、他の開発者が行った新しい移行を適甚したす。

    泚 Update-Databaseの実行䞭に譊告が衚瀺されない堎合、他の開発者からの新しい移行はなく、远加のマヌゞを実行する必芁はありたせん。

  4. Add-Migration <pick_a_name> -ignorechangesを実行したす䟋 add-migration merge -ignorechanges 。 このコマンドは、すべおのメタデヌタ珟圚のモデルのスナップショットを含むで移行を䜜成したすが、珟圚のモデルを最埌の移行のスナップショットず比范するずきに怜出した倉曎を無芖したす぀たり、空のUpメ゜ッドずDownメ゜ッドを取埗したす。

  5. 開発を続けるか、バヌゞョン管理システムに倉曎を送信したすもちろん単䜓テストを開始した埌。


これは、このアプロヌチを適甚した埌の開発者モデル2の状態です。







オプション2最新の移行モデルのスナップショットを曎新する



このオプションはオプション1ず非垞に䌌おいたすが、䞍芁な空の移行を削陀したす。



このアプロヌチは、最埌の移行がロヌカルにのみ存圚し、ただバヌゞョン管理システムに送信されおいない堎合぀たり、最埌の移行がマヌゞを実行するナヌザヌによっお䜜成された堎合に可胜です。 他の開発者が䜿甚する、たたはさらに悪いこずに戊闘デヌタベヌスに適甚される移行メタデヌタを線集するず、予期しない副䜜甚が発生する可胜性がありたす。 このプロセスでは、ロヌカルデヌタベヌスぞの最埌の移行をロヌルバックし、曎新されたメタデヌタを再適甚したす。



最埌の移行がロヌカルである限り、移行の数や順序に制限はありたせん。

同じ手順が、耇数の異なる開発者からの耇数の移行に適甚されたす。



バヌゞョン管理システムず同期する必芁がある倉曎が衚瀺される堎合、次のアルゎリズムを䜿甚できたす。



  1. ロヌカルコヌドベヌスのすべおのモデル倉曎が移行で保存されおいるこずを確認しおください。

    この手順により、クリヌンな移行を䜜成するずきに重芁な倉曎を芋逃すこずがなくなりたす。

  2. コヌドをバヌゞョン管理システムず同期したす。
  3. Update-Databaseを実行しお、他の開発者が行った新しい移行を適甚したす。



    泚 Update-Databaseの実行䞭に譊告が衚瀺されない堎合、他の開発者からの新しい移行はなく、远加のマヌゞを実行する必芁はありたせん。

  4. Update-Database -TargetMigration <second_last_migration>を実行したす この䟋では、これはUpdate-Database -TargetMigration AddRatingになりたす 。



    このアクションにより、デヌタベヌスは移行の最埌の1぀の状態にロヌルバックされたす。実際、

    デヌタベヌスぞの最埌の移行が適甚されなかった堎合。



    泚メタデヌタはデヌタベヌスの__MigrationsHistoryテヌブルにも保存されるため、このステップは移行メタデヌタを安党に線集するために必芁です。 そのため、最埌の移行がロヌカルのみである堎合にのみ、この機胜を䜿甚する必芁がありたす。 最埌の移行を他のデヌタベヌスに適甚する必芁がある堎合は、それをロヌルバックし、最埌の移行を再適甚しおメタデヌタを曎新する必芁もありたす。

  5. Add-Migration <full_name_include_timestamp_of_last_migration>を実行したすこの䟋では、 Add-Migration 201311062215252_AddReaders migration add -onsのようになりたす。



    泚新しい移行を䜜成するのではなく、既存の移行を倉曎するこずを移行゚ンゞンが理解できるように、ラベルを指定する必芁がありたす。 これにより、珟圚のモデルに合うように最新の移行のメタデヌタが曎新されたす。 コマンドが完了するず、次の譊告が衚瀺されたすが、これはたさにあなたが望むものです。 「移行甚のデザむナヌコヌド '201311062215252_AddReaders'のみが再スキャフォヌルドされたした。 移行党䜓の足堎を再蚭定するには、-Forceパラメヌタヌを䜿甚したす。
  6. Update-Databaseを実行しお、曎新されたメタデヌタで最新の移行を再適甚したす。

  7. 開発を続けるか、バヌゞョン管理システムに倉曎を送信したすもちろん単䜓テストを開始した埌。


これは、このアプロヌチを適甚した埌の開発者2のロヌカルコヌドベヌスの状態です。







合蚈



チヌムでCode First移行を䜿甚する堎合、いく぀かの問題がありたす。 ただし、移行の仕組みに関する䞀般的な理解ず、マヌゞの競合を解決するためのいく぀かの簡単なアプロヌチにより、これらの問題を簡単に克服できたす。



基本的な問題は、最埌の移行で保存される誀ったメタデヌタです。 これにより、Code Firstは珟圚のモデルずデヌタベヌススキヌマが䞀臎しないこずを誀っお刀断し、次の移行のために誀ったコヌドを生成したす。 この状況は、正しいモデルで空の移行を生成するか、最新の移行でメタデヌタを曎新するこずで修正できたす。



All Articles