web-dev-qa-db-ja.com

EF 6およびMVC 5のコードファーストアプローチを使用して、既存のデータベースに新しいテーブルを追加する

これは簡単なはずですが、このテーマに関する正しいチュートリアルや説明をウェブ上で見つけることができませんでした。コードファーストアプローチを使用して既存のテーブルに新しい列を追加することに関するビデオや投稿はたくさんありますが、新しいテーブル全体を既存のデータベースに追加する方法に関する段階的な説明はありません。奇妙なことですが、多くの例が見つかると私はかなり確信していました。多分私の検索基準は悪いです。ですから、誰かが良いリンクやビデオを持っているなら、共有してください。

私がやろうとしていることは、MVC 5プロジェクトによって作成された既存のデフォルトデータベースにテーブルPostを追加することです。最初にモデルクラスを作成し、Postという名前を付けました。単純な定義があります。

public class Post
    {
        [Key]
        public int PostId { get; set; }
        public string PostText { get; set; }
        public byte[] ImagePost { get; set; }
        public byte[] FilePost { get; set; }
        public string TextPost { get; set; }
        public string UserId { get; set; }
    } 

それから私は最初の疑問を持っています。 DbContextを作成する必要があることはわかっていますが、既存のデータベースにアクセスする場合は、次のように、Web.configファイルで既定で既に作成されている既存のDbContextを使用する必要があります。

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-StudentBookApp-20150114035149.mdf;Initial Catalog=aspnet-StudentBookApp-20150114035149;Integrated Security=True"
      providerName="System.Data.SqlClient" />

または、Postクラス用に作成されたすべての新しいDbContextを使用する必要がありますか?

とにかく両方を試しましたが、成功しませんでした。この新しいコンテキストを作成したとき、私はPMCで次のことをしていました。

Enable-Migrations
Add-Migration "PostMigration"
Update-Database

通常、またはすべてうまくいきますが、データベースに新しいテーブルを取得しないか、エラーが発生します。AspNetUsersは既に存在しており、AspNetUsersは新しい列を追加することで変更した自動作成テーブルの1つです。

更新:現在、私のコンテキストはPostContextという名前の分離されたクラスにあり、次のようになります。

public class PostContext : DbContext
{
    public PostContext() : base("name=PostContext")
    {
    }

    public DbSet<Post> Posts { get; set; }
}

2回目の試行:

私の最初のアプローチは何の結果も与えなかったので。私はこれで説明されていることをやってみました link 。プロジェクトにマッピングを追加する:

マッピング用に新しいクラスPostConfigurationを作成しました:

public class PostConfiguration : EntityTypeConfiguration<Post>
    {
        public PostConfiguration() : base()
        {
            HasKey(p => p.PostId);
            ToTable("Post");

            HasOptional(p => p.PostText);
            ToTable("Post");

            HasOptional(p => p.ImagePost);
            ToTable("Post");

            HasOptional(p => p.TextPost);
            ToTable("Post");

            HasOptional(p => p.FilePost);
            ToTable("Post");

            HasRequired(p => p.UserId);
            ToTable("Post");
        }
    }

Postクラスには、上記のリンク先で示唆されているように、modelBuilder変数を使用してコンテキストクラスPostContextも追加しました。

 public class PostContext : DbContext
    {
        static PostContext()
        {
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<PostContext>());
        }

        public DbSet<Post> Posts { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Properties()
                        .Where(p => p.Name == "Key")
                        .Configure(p => p.IsKey());

            modelBuilder.Configurations.Add(new PostConfiguration());
        }

   }

すべてのPMCコマンドを再度実行しましたが、まだ成功しません。テーブルPostがデフォルトデータベースにありません。

10
nemo_87

ここで起こったことは、移行が有効になる前に既存のデータベーステーブルがあったことです。したがって、Entity Frameworkは、データベースオブジェクトをすべて作成する必要があると判断します。これは、PostMigration移行ファイルを開くと確認できます。

最善の方法は、EFをだまして、Postテーブルを追加する前に毎回初期移行を実行し、その後にPosts移行を実行することです。

手順

  1. EFが投稿について知らないように、DBContextの投稿をコメント化する

    //public DbSet<Post> Posts { get; set; }
    
  2. 移行を有効にする

    Enable-Migrations
    
  3. 変更前のすべてのテーブルで初期移行を追加する

    Add-Migration "InitialBaseline" –IgnoreChanges
    
  4. 次にデータベースを更新します。これにより、MigrationHistoryテーブルが作成され、EFは実行された移行を認識します。

    Update-Database
    
  5. これで、1行目のコメントを解除して「変更を行う」ことができます

  6. 投稿を追加して新しい移行を作成する

    Add-Migration "PostMigration"
    
  7. 更新を行ってください...そしてうまくいけばすべてうまくいくはずです。

    Update-Database
    

これで移行はすべてセットアップされ、ベースラインになっているため、将来の移行は簡単になります。

詳細については、このリンクが役立つと思いました: http://msdn.Microsoft.com/en-us/data/dn579398.aspx

18
Oliver