コンテキストに加えられた変更を保存しようとすると、次のエラーが表示されます。
ストアの更新、挿入、または削除ステートメントは、予期しない行数(0)に影響しました。エンティティがロードされてからエンティティが変更または削除された可能性があります。 ObjectStateManagerエントリを更新します。
次のクラスがあります。
人
_public class Person : IPerson
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name
{
get
{
return FirstName + " " + LastName;
}
set{}
}
public string Email { get; set; }
public DateTime? LastModified { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
_
UserProfile
_public class UserProfile : Person
{
public UserProfile()
{
Faculty = new Faculty();
Projects = new Collection<Project>();
Results = new Collection<Result>();
}
public string UserName { get; set; }
public string CNP { get; set; }
public virtual Faculty Faculty { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
_
結果
_public abstract class Result:INamedEntity
{
protected Result()
{
ResultType = new ResultType();
}
public int Id { get; set; }
public string Name{get;set;}
public virtual ResultType ResultType { get; set; }
public virtual ICollection<Person> People { get; set; }
public DateTime? LastModified { get; set; }
}
_
次を使用してコンテキストに値を追加した後:
__ctx.Users.Single(u => u.Id == userId).Results.Add(result);
_
_ctx.SaveChanges()
を呼び出すとエラーが発生します
私の機能を更新しました:
_public bool Save()
{
try
{
_ctx.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Users);
((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Results);
_ctx.SaveChanges();
}
return true;
}
_
しかし、エラーは捕捉されません。ありがとうございました
理解した。問題は、このプロジェクトで作業しているのが2人で、同僚がDBContext
の独自のインスタンスを作成し、一方と他方を更新していることです。したがって、将来この問題を抱えている人のために、同時にDBContext
の2つの異なるインスタンスを持たないようにしてください。
これをedit.cshtmlに追加します
@Html.HiddenFor(model => model.Id)
私はこの問題を抱えていましたが、IDがページ上にないため0として認識されていました。
私はViewModelにもこれを持っています(ビューモデルアプローチを使用しています)
[HiddenInput(DisplayValue = false)]
[Key]
public int Id { get; set; }
例外とは、データベースからデータを取得して変更した時点で、データが変更されていたことを意味します。
既定では、Entity Frameworkは楽観的同時実行モデルを実装しています。これは、データがクエリされてからデータが更新されるまでの間、データソースのデータに対してロックが保持されないことを意味します。 [〜#〜] msdn [〜#〜]
オブジェクトコンテキストで同時実行性を管理する方法. [〜#〜] msdn [〜#〜]
または、コンテキストを更新するこの回答に従ってください。 StackOverflow
私にとっての問題は、action bindingsを正しく設定していなかったことです:
public ActionResult Edit([Bind(Include = "VehicleID,Name,CreateDate,PowerPS,DrivenKM")] Car car)
{ ... }
VehicleIDは誤った識別子でマップされたため、Entity Frameworkは常に0を主キーとして取得しました。
この問題に遭遇し、上記の解決策のどれもがあなたを助けたことがなければ、多分あなたはこれを試すことができます。私はこの奇妙な問題も抱えていました。それを修正する方法は、フィールドを主キーに設定し、自動インクリメントまたはアイデンティティに設定することです。 Personテーブルがあり、personIDがある場合、プライマリキーに設定し、自動インクリメントされることを確認します。
dbContextクラスに次のオーバーロードを追加します。
_using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
public class MyDbContext: DbContext {
...
public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
try {
return SaveChanges();
}
catch (DbUpdateConcurrencyException ex) {
foreach (DbEntityEntry entry in ex.Entries) {
if (refreshMode == RefreshMode.ClientWins)
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
else
entry.Reload();
}
return SaveChanges();
}
}
}
_
次に、適用可能な場合はいつでもSaveChanges(true)
と呼ばれます。
私もこのエラーメッセージに遭遇しました。私のエラーの原因は、プライマリ/外部キーの競合です。いくつかの新しいデータをDBにプッシュしましたが、外部キーの値はオフでした(アップロードスクリプトの間違い)。
SQLプロファイラーを使用して、問題の挿入スクリプトを追跡します。これにより、更新の問題を発見するのに役立ちます。
これが同様の問題を抱えている他の誰にも役立つことを願っています。
楽観的ロックを使用しているため、競合があります。 ObjectStateManagerエントリを使用して同時実行の問題を解決し、変更を再度保存します。サンプルコードは [〜#〜] msdn [〜#〜] siteにあります。
私の場合、複合キーがあり、その一部を更新しようとしました(3列は複合キーを構成し、そのうち3列目のみを更新していました)が、EFは同じオブジェクトのキー値を変更できませんでした、私は以下を介してレコードの更新を達成しました。
Context.Database.ExecuteSqlCommand(udpateCommand);
さて、Code Firstを使用してEntity Framework 6.13を操作しているときに、このタイプの同時実行エラーに直面しました。また、自分で解決するまで何時間も苦労しました。だから、そこにいる誰かを助けることができます。複合主キーを使用してテーブルが作成され、今日、複合キーの代わりにテーブルの構造を変更し、主キーを1つだけ(AutoIncrementを使用して)作成し、fluent-api構成での移行によりテーブルを更新しました。テーブルは更新されましたが、主キーはAutoIncrementで更新されず、レコードを追加しようとすると、同時実行エラーが表示されました。そのため、フィールドの自動インクリメントを設定すると、エラーはなくなりました。それが役に立てば幸い。
何が間違っていたのかはわかりませんが、これらの手順を実行しただけで解決しました。 (私ができたので、あなたがこれを解決できることを願っています)
手順は次のとおりです。
(1)edmxテーブルとEFファイルのDBコンテキストに基づいて、scaffoldingを使用して新しいコントローラーを追加します。
(2)ここで、変更を保存すると問題が発生するのはeditメソッドです。
(3)次に、足場から作成された編集メソッド/コントローラー全体をコピーし、元のコントローラーに貼り付けます。
(4)プログラムをビルドするだけで、Voila準備完了です。
更新
ビューからデータを編集するには、すべてのフィールドを送信してコントローラーに再度書き込む必要があることがわかりました。編集時にエンティティテーブルのフィールドのいずれかが欠落している場合、編集することはできません。特にPKがラベルにあり、編集のためにコントローラーに送信された場合、このエラーが生成されます。
プロジェクトを作成するときに、単純な挿入を実行しようとしても、このエラーが発生しました。
既存のデータベースからEFモデルを生成していましたが、フレームワークは自動的にEntity Key = True
複数のフィールド。
ID以外のすべてをFalse
に設定すると、問題は解決しました。
グーグルのときにこれに出くわした。私は同じエラーメッセージを持っていましたが、理由はいくつかの必須の非ヌル値を設定しなかったことが判明しました。
たぶん、この発見は誰かを助ける。
Terryに感謝します。これを追加しましょう:足場を作成するときにキー/ IDに[必須]属性を追加しないでください。これにより、コンテキストがURLからキー/ IDを取得できなくなります。また、移行後にモデルに新しいブール値フィールドが含まれるscaffoldコントローラーでこれが発生しました。これらのフィールドは設定されていません。
ビューから両方のテーブルのIDをモデルに渡していることを確認してください。あなたの場合、それはテーブルPersonとUserProfileのキーです。ページにIDを表示する必要がない場合は、@ Html.HiddenFor(model => model.PersonId)および@ Html.HiddenFor(model => model.UserProfileId)を追加できます。