web-dev-qa-db-ja.com

EntityFrameworkによる自動番号付け

オブジェクトのコレクションをループして、それらすべてをテーブルに追加したいと思います。宛先テーブルには自動インクリメントフィールドがあります。オブジェクトを1つ追加しても問題ありません。主キーがゼロの2つのオブジェクトを追加すると、エンティティフレームワークが失敗します。主キーを手動で指定することはできますが、EFを試すことの全体的なポイントは、作業をより簡単にすることであり、それほど複雑ではありません。コードと受け取った例外は次のとおりです。

foreach (Contact contact in contacts)
{               
    Instructor instructor = InstructorFromContact(contact);             
    context.AddToInstructors(instructor);               
}

try
{                   
    context.SaveChanges();                  
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

エラーは次のとおりです。

System.InvalidOperationException:データベースへの変更は正常にコミットされましたが、オブジェクトコンテキストの更新中にエラーが発生しました。 ObjectContextが一貫性のない状態になっている可能性があります。内部例外メッセージ:オブジェクトのキー値がObjectStateManager内の別のオブジェクトと競合しているため、AcceptChangesを続行できません。 AcceptChangesを呼び出す前に、キー値が一意であることを確認してください。 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)で
C:\ Projects\DataMigration\Program.cs:line 52のDataMigration.Program.CopyInstructors()のSystem.Data.Objects.ObjectContext.SaveChanges()

16
dcompiled

自動インクリメントフィールドのSSDLでStoreGeneratedPattern属性を「Identity」に設定します。それは役立つはずです。

19
Devart

これは、列の自動生成された値がデータベースで作成されたにもかかわらず、EFがそれを知らなかったために発生します。

したがって、生成された値をDBが処理することをEFに通知するには、edmxファイルを開く必要があり(これを行うには常にVSのXMLエディターを使用します)、ストアスキーマ定義言語(SSDL)領域に属性StoreGeneratedPattern = "Identity"生成されたパターンを必要とする列に。このようにして、EFはDBで生成された値を読み取り、それをメモリキャッシュに保存します。

エンティティタイプの定義は、多かれ少なかれ次のようになります。

 <EntityType Name="INVOICE">
          <Key>
            <PropertyRef Name="CODE" />
          </Key>
          <Property Name="CODE" Type="varchar" Nullable="false"
              MaxLength="10" StoreGeneratedPattern="Identity"/>                 
 </EntityType>

モデルを更新すると、これらの変更はすべて失われ、プロセス全体を繰り返す必要があることに注意してください。

これはEF1.0で機能しますが、EF4でこれらすべての問題がすでに修正されているかどうかはわかりません。

12
cepriego

EF6を使用して、StoreGeneratedPatternを設定します。また、Visual StudioでEDMXファイルを開いて、テーブルのデータ列を右クリックし、[プロパティ]を選択することもできます。

次に、プロパティウィンドウでNoneからIdentityに設定できます。

3
yu yang Jian