2016-08-22 14 views
1

私は2つのSQL Expressデータベースを持っています。最初のデータベースにはデータがたくさんありますが、新しいアプリケーションを構築して同様のテーブル構造(いくつかのカラムを追加し、いくつかを削除し、いくつかのテーブルをマージしました。クライアントは同じで、新しいアプリケーションで古いデータを使用したいと考えています。Entity Framework C# - 類似の構造を持つあるデータベースから別のデータベースへデータを移動する

私は今、何をしようとしているのは、古いDBからデータを(テーブルごとに)移動し、(手動で)古いフォーマットから新しいフォーマットにエンティティを変換し、 DB。

私はEntity Frameworkを使用しています。サーバーはASP.NET Web Apiです。 2つの別々のDbContextを作成しました.1つは古いDB用、もう1つは新しいもの用です。 私は古いDBから自分のデータを取得して変換することができますが、私は自分の問題にぶつかります。私は古いDBに存在する関係を維持できるように、同じままにするためにIdentity列が必要です。エンティティを保存しようとすると、EFはIdentity_InsertがオフのときにID列に値を挿入できないことを伝えます。

これは私の実際のエラーメッセージです:IDENTITY_INSERTがOFFに設定されている場合

は「AccessoryProfiles」テーブルにID列の明示的な値を挿入することはできません。

ここでデータを移行しようとする私のコントローラのメソッドです:DataServiceは新しいものを扱うながら

public IHttpActionResult Get() 
     { 
      try 
      { 
       var manager = new MigrationManager<AccessoryProfile>(); 

       var entities = manager.GetAll(); 


       foreach (var profile in entities) 
       { 
        var newEntity = new Entities.Server.Accessories.AccessoryProfile 
        { 
         Id = profile.AccessoryProfileId, 
         Name = profile.Name, 
         CreatedDate = profile.CreatedDate, 
         LastModifiedDate = profile.LastModifiedDate, 
         DeletedDate = profile.DeletedDate 
        }; 

        DataService.AccessoryProfile.Add(newEntity); 
       } 

       DataService.AccessoryProfile.Commit(); 

       return Ok(); 
      } 
      catch (Exception exc) 
      { 
       Logger.Error(exc); 
       return null; 
      } 
     } 

MigrationManager<T>は古いDBを処理します。 Idで[DatabaseGenerated(DatabaseGeneratedOption.None)]を設定しようとしましたが、運がありません。

DbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [dbo].[AccessoryProfiles] ON");

を...しかし、私はまだID列に値を挿入することはできません:私は)(私のコミット前にこれを実行してみました。

どのようにEntity Frameworkでこれを行うことになっていますか? EFを使用するよりも良い方法が分かっていれば、私はすべて耳にします。 ありがとう!

+0

SQL Serverのデータを '.csv'にエクスポートし、' .xls'に変換して新しいdbにインポートすることができます。 '.xls'ファイルのスキーマを変更することは問題ではありません。 –

+0

SQLクエリでこれを行うことはできませんか?データを転送するこのアプローチは深刻な頭痛になる可能性があります。あなたは、このような他の多くの問題に直面する可能性があります。これらの問題はすべて、SQLで扱いやすくなります。私はあなたがselect ...などから挿入するようなクエリを書くことをお勧めします。また、プライマリキーと外部キーの間の参照整合性について心配することを忘れないでください。幸運。 –

+0

DbContext.Database.ExecuteSqlCommandを実行していることを確認してください( "SET IDENTITY_INSERT [dbo]。[AccessoryProfiles] ON");送信側のデータベースコンテキストではなく、受信側のデータベースコンテキストに対して –

答えて

2

テーブル全体を挿入する場合は、EntityFramework.BulkInsertの使用をお勧めします。多くのレコードでは、 ".Add"や ".AddRange"拡張はかなり遅いです。ここで

がbulkinsertの説明と速度の利点です: https://efbulkinsert.codeplex.com/

enter image description here

あなたはまた、より多くの情報のため、このスレッドをチェックアウトすることができます:あなたのSqlBulkCopyを設定するとき Fastest Way of Inserting in Entity Framework

、それが可能に別のSqlBulkCopyOptionsでそれをオーバーロードする必要があります。私は彼らのうちの1人がソースアイデンティティを保つことを可能にする "KeepIdentity"だと信じています。私はそれがあなたが探しているものかもしれないと思います。

SqlBulkCopy copy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.KeepIdentity| SqlBulkCopyOptions.Default, null); 

また、あなたが「CHECKCONSTRAINTS」オプションを使用していないことを確認してください:あなたはsqlbulkcopyオブジェクトを設定するときに

ですから、このような何かを書くかもしれません。

+0

ありがとうございます。私はこの作業をしようとしている、私はKeepIdentity設定を見つけたと私はキーの挿入エラーを取得しません。しかし、私は "DbContextをバックアップしているモデル"が変更されています... "私は新しい移行を試みましたが、保留中の変更はありませんでした。私はデータベースを削除し、最初にコードを使用して再作成しましたが、このエラーが発生します。私はまだ上記と同じ方法を実行します。 'の代わりに'DbContext.Add(エンティティ)の ;;'の違いは、私が( { SqlBulkCopyOptions = SqlBulkCopyOptions.KeepIdentity }エンティティ、新しいBulkInsertOptions)'DbContext.BulkInsertを実行することである私のDataServiceで 。何か案は? –

+0

ところで、エラーは私の古いデータベースではなく、私の新しいデータベースのDbContextを指しています。 –

+1

何らかの理由でBulkInsertをインストールしたときにEntity Frameworkが6.0.0にダウングレードされたため、エラーが発生しました。私はEFを更新し、エラーは消えました!そして、あなたのソリューションはスムーズに動作しました。新しいDBに正しいID列を使用して、テーブル全体をフォーマットして準備しました。どうもありがとう! –

関連する問題