Entityオブジェクトを追加または更新する次のコードがあります。オブジェクトを追加または更新している応答に基づいて、主キーでオブジェクトを見つける。
レコードの追加は機能しますが、更新中にこのエラーメッセージが表示されます。「同じキーを持つオブジェクトがObjectStateManagerに既に存在します。ObjectStateManagerは同じキーを持つ複数のオブジェクトを追跡できません」
私のMSSQLデータベースには、レコードが1つしかありません。
var v = db.Envelopes.Find(model.ReportDate, model.Service);
if (v == null)
{
db.Envelopes.Add(model);
db.SaveChanges();
ViewBag.status = "Record Add successfully";
ModelState.Clear();
}
else
{
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
}
このエラーメッセージを修正するにはどうすればよいですか?
@anonで述べたように、同じキーでエンティティをロードすると、モデルをアタッチできません。変更は、添付されたエンティティに適用する必要があります。これの代わりに:
db.Entry(model).State = EntityState.Modified;
これを使って:
db.Entry(v).CurrentValues.SetValues(model);
以前のクエリが更新するエンティティを読み取ったためにエラーが発生した場合は、そのクエリをAsNoTrackingに変更できます。次のAsNoTrackingの例を参照してください。 http://www.asp.net/entity-framework/tutorials/advanced-entity-framework-scenarios-for-an-mvc-web-application
ここでエラーが発生すると言っていると思います:
db.Entry(model).State = EntityState.Modified;
Find()を実行すると、エンベロープは既にコンテキストによって追跡されています。つまり、プロパティを変更する必要がある場合は、vでプロパティを変更してからSaveChanges()を呼び出すだけです。状態をModifiedに設定する心配はありません。
コンテキストをAsNoTracking()に設定すると、メモリ内のエンティティへの変更を追跡するaspmvcが停止します(これはWeb上で必要なことです)。 usingステートメントを忘れないでください。
using System.Data.Entity;
db.Envelopes.AsNoTracking().Find(model.ReportDate, model.Service);
私はこのフォーラムの投稿からこれを得ました-> http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an -mvc-web-application
既に新しいインスタンスを作成し、更新する必要があるプロパティを設定しているため、これを使用しています。
var key=this.CreateEntityKey("Envelopes",model);
ObjectStateEntry ose;
if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
var entity=(Page)ose.Entity;
Envelopes.Detach(entity);
}
this.Envelopes.Attach(model);
この問題を解決する別のアプローチは、追跡されたエンティティをデタッチし、変更されたエンティティを再アタッチします。私の解決策を参照してください こちら 。