25

私はさまざまなオブジェクトをデータベースに永続化するためにEntity Framework 4.1を使用するプロジェクトで作業しています。Entity Framework 4.1データベースの作成後、コンテキストのバッキングモデルが変更されました。

Visual StudioでローカルSQL Express DBを使用してテストしており、Jenkinsサーバーはコミット済みコードをテストサーバーに展開します。これが発生すると、一時的に私のローカル接続文字列を変更してテストDBサーバを指し示し、単体テストを実行してテストデータベースを再作成し、最新のエンティティなどに一致させる。

私は最近サーバーがこのエラーを表示しています:

データベースが作成されて以来、 'EntityFrameworkUnitOfWork'コンテキストを裏付けるモデルが変更されました。データベースを手動で削除または更新するか、IDatabaseInitializerインスタンスを使用してDatabase.SetInitializerを呼び出します。たとえば、DropCreateDatabaseIfModelChanges戦略では、データベースが自動的に削除され、再作成され、必要に応じて新しいデータでシードされます。

これは通常、私たちのコードが変更されたことを示しています。ユニットテストを実行してデータベースを再作成する必要があります。私はちょうどそれを除いて!私は展開プロセスに何か問題があるとは思わない - テストサーバー上のDLLは、私のローカル環境と同じバージョンであるようだ。データベースが作成されてからモデルが変更されたことに関するこのエラーの原因となるその他の設定や環境要因はありますか?

私はここです - 何か助けてくれてありがとう!

+1

'System.Data.Entity.Infrastructure.EdmMetadata.TryGetModelHash(YourDbContext)'メソッドを使用してModelHashを取得し、ローカルPCとテストサーバー上でそれらが異なるかどうかを確認できますか? – Marc

+0

データベースを再生成した後にコンテキストまたはPOCOを再生成するためにカスタムツールを実行しましたか? –

+1

@Marcはい、ハッシュは異なるようです。 – DaveBeta

答えて

25

エラーは、EdmMetadataテーブルに格納されているモデルハッシュが、アプリケーションのモデルから計算されたモデルハッシュと異なることを示しています。別のアプリケーション(デベロッパーアプリケーション)からデータベース作成を実行しているので、それらの2つが異なる可能性があります。ここでの簡単なアドバイスは、データベースの作成に別のアプリケーションを使用せず、主アプリケーションがデータベースを作成できるようにすることです(管理インターフェースを使用して自動的に行うなど)。

modelBuilder.Conventions.Remove<IncludeMetadataConvention>(); 

モデルのハッシュ計算は、アプリケーションの現在のエンティティに依存している(いずれかの簡単な変更の結果で:あなたはこれらのチェックを担当する規則を削除することによって、完全にこのチェックをオフにすることができるはずです別のオプションとして

異なるモデルハッシュ)とデータベースサーバーバージョン/マニフェストに適用されます。たとえば、SQL Server 2005および2008にデプロイされたモデルは、異なるモデルハッシュ(Express vs. Fullまたは2008年版と2008年版のR2で異なるモデルハッシュにならない)を持つことになります。

+0

デスクトップとサーバーには異なるOSバージョンがあります。私はSQL Expressをローカルで使用していますが、UATでは使用していないため、いくつかの異なるバージョンのSQL Serverがあります。これらのプラットフォームの違いが別の 'EdmMetadata'ハッシュを引き起こすという人生の事実だけがあれば、私は単純に規約を削除してハッシュの作成/チェックを無効にすることができます。ありがとう! – DaveBeta

+0

'警告 'System.Data.Entity.Infrastructure.IncludeMetadataConvention'は廃止されました: 'IncludeMetadataConventionは使用されなくなりました。 EdmMetadataはモデルに含まれていません。 はモデルの変更を検出するために使用されます。 \t ** ** 2013 **回答はEF4に関連しなくなりました – ppumkin

+0

@ppumkin:EF4.3より前に回答があった –

2

エンティティフレームワークコードは、最初にEdmMetadataというテーブルを作成します。現在のモデルのハッシュを保持します。アプリケーションを実行すると、EFは使用されているモデルがdbが知っているモデルと同じであるかどうかをチェックします。

データベースの移行を実行する場合は、まだアルファですが、EF Code first migrationsを使用することをお勧めします。

あなたが移行を使用したくない場合は次のいずれかを実行できます

を手動でスキーマの変更を処理 - すべての変更に伴い、テストサーバーへEdmMetadataテーブルの内容を移動することを意味し

db初期化子をDropCreateDatabaseIfModelChanges(またはそれから派生したもの)に設定し、Seed()メソッドを使用して初期データを書き込みます。これは役立つかもしれないとスコットGのブログへのリンクが必ずあなたの問題への解決策となります

<add key="DatabaseInitializerForType Fully.Qualified.Name.Of.Your.DbContext," value="Fully.Qualified.Name.Of.The.Initializer" /> 
+1

ありがとう。私の謎は、私が知る限り、同じものであることは確かに2つのアプリケーションサーバを持っているという事実に関連していました - 確かにDLLは同じですが、どちらも両方とも "違う"と思うようです。私は、EdmMetadataテーブルを削除するだけで、エラーを抑制することができ、両方のアプリケーションが同じデータベースでうまく動作しているように見えることがわかりました。これは間違っているようです! – DaveBeta

+0

デプロイ時に同様の問題が発生しました.DLLを単純に再コンパイルして再デプロイしても問題は解決します。 – JarrettV

3

のappSettingsを開始したり、使用するアプリケーションの場合)のいずれかinitialzerを設定する(Database.SetInitializerを呼び出すには、この質問にlink

をチェック

編集1:これはlink to Scott G blog

編集2:あなたが最初の統合サーバー

編集3上のデータベースを使用する場合にも、thisを確認することがあります。これがですはScott Gのものと似ています

+0

@ダウンボートを持つ人:少なくとも答えを確認しようとしましたか? –

9

これは、異なるプラットフォーム間の反射順序の違いによって発生します。確認するには、EdmxWriter APIを使用して、両方の環境からのEDMXを比較できます。いずれかの表の列順序が異なる場合は、これが問題です。

回避策として、ローカルデータベースではなくテストサーバーから更新されるように、テストデータベースの更新方法を変更することができます。

次のリリースでこの問題を修正する予定です。

+0

これはビルド構成にも基づいて違いがありますか?つまり、デバッグとリリースの違い? – JarrettV

3

アプリケーションを実行している2つのサーバーが異なるオペレーティングシステム(またはサービスパック)を実行していますか?使用されているSHA256CryptoServiceはPlatformNotSupportedExceptionをスローして別のメソッドにフォールバックさせることができます。

http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256cryptoserviceprovider.sha256cryptoserviceprovider.aspx

// System.Data.Entity.Internal.CodeFirstCachedMetadataWorkspace 
private static SHA256 GetSha256HashAlgorithm() 
{ 
    SHA256 result; 
    try 
    { 
    result = new SHA256CryptoServiceProvider(); 
    } 
    catch (PlatformNotSupportedException) 
    { 
    result = new SHA256Managed(); 
    } 
    return result; 
} 

各サーバー上で以下の2(内部/プライベート)メソッドを呼び出すためにリフレクションを使用してこれをテストすることができるかもしれません。

MetaDataWorkspace.ToMetadataWorkspace(DbDatabaseMapping, Action<string>) 
CodeFirstCachedMetadataWorkspace.ComputeSha256Hash(string xml); 
+0

同じ結果を生成する必要がある管理対象のバージョンに戻ります。 – JarrettV

6

コードファーストアプローチでは、SSDLがコードの実行中に生成されます。生成されるSSDLに含まれる情報の1つは、DbConnectionで使用されるプロバイダの名前です。あなたが言ったように、あなたは異なるデータベースエンジンに接続しているので、2つの異なるプロバイダを使用する必要があります。これにより、ハッシュ関数の出力が完全に変更されます。

次のコードは、EntityFrameworkアセンブリから抽出した:私は誤って私の.mdfファイルのファイルの名前を変更してこのエラーを得た

using (XmlWriter writer = XmlWriter.Create(output, settings)) 
{ 
    new SsdlSerializer().Serialize(database, providerInfo.ProviderInvariantName, providerInfo.ProviderManifestToken, writer); 
} 
+0

私はデバッグとリリースの違いを見ていますが、プロバイダの変更はありません – JarrettV

+0

これは私の質問に答えることはできませんが、元の質問に答えています。ここにあなたの恩恵があります。 – JarrettV

0

。だからこれも見てください。

関連する問題