26

EF 移行を使用して理解しようとしています (EF 4.3.1、Code First を使用)。新しい変更を足場にするには、次のようなコマンドを使用する必要があります。

Add-Migration MyMigration
   -ConnectionString "Data Source=.;Initial Catalog=mydb;" 
   -ConnectionProviderName "System.Data.SqlClient"
   -StartUpProjectName MyWebsite 
   -ProjectName MyEF.Migrations

Add-Migration で接続文字列データが必要なのはなぜですか? Update-Database必要です、それは理にかなっています。しかし、Add-Migration には、DbContext と構成から必要なものがすべて揃っているのではないでしょうか?

単にアイドル状態の不思議ではありません。データベースを指定するのは非常に混乱します。これは、目的のデータベースが柔軟で、静的コンパイル時は言うまでもなく、要求ごとに変更される可能性がある「マルチテナンシー」があるためです。したがって、Add-Migration実際にそのデータベースを何かに使用している場合、問題があります。

更新: EF 移行をあきらめ、代わりにFluent Migratorを使用しています。満足しています。いくつかのことを2回(EFオブジェクト用に1回、移行用に1回)書く必要があるという事実を数えても、はるかに高速であり、この質問で説明されている問題はありません。

4

4 に答える 4

13

Add-Migrationデータベースの存在をチェックし、テーブルと対話し__MigrationHistoryます。@Anders Abelが述べたように、保留中の移行を調査したり、以前のモデルを選択して変更内容を実際に見つけたりするために使用されます。これは、自動移行が有効になっているソリューションに明示的な移行を追加する場合に特に重要です。

于 2012-05-29T19:35:15.630 に答える
10

あなたの質問を読んで気になったので、Sql Server Profiler を起動して、add-migration の実行時に何が起こっているかを調べました。実際にデータベースに接続し、DB にアクセスして__MigrationHistoryテーブルをチェックします。

これは、最初の移行を実行せずに 2 番目のコードベースの移行を作成しようとしたときに生成されるエラー メッセージによっても示されます。

次の明示的な移行が保留中のため、明示的な移行を生成できません: [201205291928386_foo]。新しい明示的な移行を生成する前に、保留中の明示的な移行を適用してください。

移行エンジンは、データベースからシリアル化されたモデルを使用して、新しい移行にどの移行ステップを含める必要があるかを計算していると思います。

私の知る限り、データベースはコード生成のヘルパーとしてのみ使用されます。使用するさまざまなデータベースがコード内のモデルと互換性がある限り、これは問題にはなりません。

編集

@Ladislav Mrnka が指摘しているように、コードベースの移行と自動移行が混在している場合は、データベースのチェックが必要です。新しい移行を足場にするときは、最後の移行以降にモデルで変更されたものをすべて含める必要があります。自動移行を使用している場合、それらはコードで追跡されません。移行に含める変更を計算するときは、最後に実行された移行がベースとして使用されます。自動移行がオンになっている可能性があるため、それを確認する唯一の方法はデータベースです。

コードベースの移行のみで実行している場合 (これが制御を維持する唯一のオプションだと思います)、そのデータベースは単なるコード生成の助けと見なすことができます。接続するすべてのデータベースでモデルの互換性が確保されている限り、すべてが機能するはずです。

于 2012-05-29T19:32:46.777 に答える
0

OP さんが書きました:

しかし、Add-Migration には、DbContext と構成から必要なものがすべて揃っているのではないでしょうか?

いいえ - 他の人がここで述べたように、手動移行のコードのデザイナー部分 (によって作成されたものadd-migration) には、データベース スキーマのスナップショットが含まれています。

そうは言っても、接続文字列などを使用しているという事実は非常に奇妙です。EF は通常、DbContext クラスと Web.Config からそれを暗示します。1 つのデータベースと 1 つの DbContext を持つプロジェクトで、構成クラスを作成し、次を使用して手動移行を追加します。

add-migration

他のコマンド ライン引数を渡す必要はありません。それは EF 4.3.1 にあります。おそらく、CTP または古いバージョンを使用していたのでしょうか、それとも単にドキュメントを誤解していたのでしょうか?

複数の DB または DbContext がある場合、複数の構成クラスがあり、たとえば次のように使用します。

add-migration -conf Log

これは、構成クラスと Web.config の関連する接続文字列を使用して、そのデータベース/DbContext の手動移行を追加します。

ログを保存するための単純な DbContext の長いコード例を次に示します (メインのデータベースとは別):

namespace MyProj.Models.Log
{
    public class LogDb : DbContext
    {
        public DbSet<LogLine> LogLines { get; set; }
        public DbSet<LogTag> LogTags { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }

    public LogDb()
#if DEPLOYDB
         : base("LogDeploy")
#else
         : base()
#endif
     {
     }
}

namespace MyProj.Migrations
{
    internal sealed class Log : DbMigrationsConfiguration<LogDb>
    {
        public Log()
        {
            AutomaticMigrationsEnabled = true;
        }
    }
}

Web.Config で:

<add name="LogDb" connectionString="Initial Catalog=Log;Data Source=.\SqlExpress;Integrated Security=SSPI;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
<add name="LogDeploy" connectionString="Initial Catalog=Log;Data Source=00.00.000.00,12345;User ID=sql;Password=xxx;Network Library=DBMSSOCN" providerName="System.Data.SqlClient" />

したがって、この例では、複数のデータベースと複数の DbContext があります。LogDb は、コンパイル時に "DBDEPLOY" が定義されているかどうかに基づいて、Web.Config で異なる接続文字列を使用します。存在する場合は、「LogDeploy」を使用します。そうでない場合は、デフォルト (クラスと同じ名前の接続文字列 "LogDb") が使用されます。これにより、プロジェクト構成を切り替え、SQL db マシンでポートを開き、次を実行することで、DB の変更をローカル マシンからサーバーに簡単にデプロイできます。

> update-database -conf Log

パッケージ マネージャー コンソールで。

于 2012-09-11T21:34:41.143 に答える