Error Message: Row not found or changed.
Stack Trace:
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
これは一見ランダムに発生します。これらのエラーがメールで送信されますが、報告されたURLは常に機能しているようで、他のすべてのユーザーにも機能するはずです。
このエラーは次の方法で修正できます。
dbml
レイアウトに移動しますUpdate Check
からNever
これにより、これらのタイプのエラーがスローされるのを防ぐことができます。
しかし、これは、dmbl
に機会を与えたり、新しいテーブルを追加したりするたびに実行し続けることを覚えておくのは面倒です。この問題を解決するより良い方法はありますか?私はおそらくこれらの50-100を一日に得ていますが、これは私の訪問者にとって悪いことです。
このエラーが表示されるたびに、レコード/オブジェクト/その他をロードしてから保存しようとしたときにデータベースで何かが変更されたことを意味します。間違いなく、私の仕事の単位が大きすぎたからです。
私はあなたのアプリケーションの正確な性質を知りませんが、私はあなたがデータコンテキストを作成し、レコードまたはレコードのリストをロードし、それにいくつかの操作を実行し、いくつかの時間とプロセッササイクルを噛み砕いて、それから変更したデータをデータベースに保存しようとするのをやめます。たぶん、レコード/オブジェクトのインスタンスをロードして、それをクラス変数にしばらく保存してから、ページのロードやスレッド、または変更されたものを保存しようとするものの最後に。問題は、LINQがそのコピーを格納しているため、それが更新したいコピーであるということです。その間に基になるデータが変更されると、それは狂ってしまいます。
オブジェクトの存続期間全体にわたってデータにロックトランザクションを実行するとどうなるでしょうか。あなたがロードしたものは変更されるかもしれないと言ってください。基本的にそれがここでの仮定です。確かに、LINQはそれについてもう少し楽観的であり、データを更新しない可能性がある場合に行またはテーブルをロックする意味はありませんが、これらの問題について考えます。オブジェクトに厳密なトランザクションロックを設定した場合、何が大幅に機能しなくなったり遅くなったりするのかを自問してください。そうすると、問題のあるコードが見つかる可能性があります。
これに対する私の解決策は、私の作業単位をできるだけ小さく保つことです。オブジェクトをロードして作業コピーとして使用し、データベースにすべて1つのコンテキストで保存しないでください。代わりに、オブジェクトをロードして必要な情報を1つのステップで引き出し、適用する必要のある変更を把握してから、オブジェクトをロード/更新/保存します。確かに、データベースへのラウンドトリップが多くなりますが、データの最新のコピーで作業していることをよりよく保証します。それでも「ラストイン、勝ち」になります。つまり、データの操作中に誰かが更新を行った場合、データが失われる可能性がありますが、トランザクションでレコードをロックしない限り、それは常にリスクです。ただし、他の誰かが同じ行の無関係なフィールドを変更している場合、両方がそのデータを一緒に操作できるという柔軟性が得られます。
同じ問題があり、dbmlをdb構造と比較することで解決しました。 1つのプロパティがnull許容に設定されていなかったため、問題が発生していました。
したがって、dbmlとnull許容プロパティを確認してください。
GetTable()。Attach(newEntity、originalEntity);
バージョンフィールドを使用して更新していない場合、上記のメソッドは新しい詳細エンティティと古い詳細エンティティをパラメータ化します。この時点で元のエンティティを変更しても同じエラーが発生する場合は、これを確認する必要があります。これは魅力のように機能し、私はそれを試しました。
これは、特定の列を更新していない場合でも、データベーストリガーが更新中の行の列を変更した場合にも発生する可能性があります。
作業単位で影響を受けるテーブルのいずれにもトリガーがないことを再確認する必要があります。更新トリガーを使用している場合は、更新された列がNeverCheckであることを確認する必要があります。
時にはそれは本当に簡単です...テーブルにロックがないことを確認してください。私の場合、SQL Server Management Studio UIは、デバッグ中に知らなかった(覚えていなかった)ロックを保持していました。それをアンロードすると、それらのロックがクリアされ、物事が再び機能し始めました。
SQLプロファイラーを使用してサーバーへのSQLトランザクションを追跡し、SubmitChanges()
で送信されたUPDATE
ステートメントのWHERE
句に間違った値が含まれていることに気付きました。これは、次のようなプロパティがあるためです。
_class Position{
...
[Column]
public int Pieces{
get{
this.pieces = this.Transformers.Count;
return this.pieces;
}
set{ this.pieces = value; }
}
...
}
_
Transformers
は別のTransformers
テーブルへの1対多の関係のリストを表す_List<Transformers>
_要素であるため、Transformer
オブジェクトへの外部キーを含む各Position
を手動でリストに入力する必要があります。何らかの理由でこれを行わないと、Pieces
プロパティが元の値から偏っているため、前述のエラーが発生します。
したがって、SubmitChanges()
のSQLステートメントはエントリ_WHERE Pieces = somevalue
_を検索しますが、エントリ内のPieces
の実際の値はanothervalue
です。したがって、基本的にLINQは、dbがこの要求に値を返さないため、db内で何かを変更したと見なします。
前述のように、1つの解決策は次のとおりです。
_ [Column(UpdateCheck=UpdateCheck.Never)]
public int Pieces
{
get {
this.pieces= this.Transformers.Count;
return this.pieces;
}
set { this.pieces= value; }
}
_
もちろん、これは次のような単純なゲッター関数を設定することでも簡単に解決できます。
_getPieces(){
return this.Transformers.Count();
}
_
および「偏りのない」プロパティ
_class Position{
...
[Column]
public int Pieces{
get{ return this.pieces; }
set{ this.pieces = value; }
}
...
}
_
これが誰かのお役に立てば幸いです。これを投稿したのは、他の誰かが以前に持っていたとしたら、私の人生の何時間も節約できたからです。
同じ問題に直面しました。行を更新すると問題が発生します。
たとえば、列を持つテーブルがあります:
id,firstname,lastname,age
そして、dbmlを使用して年齢を更新したいと思います。プロファイラーでupdate age=@newage
を参照してください。ここで、id=@id
およびfirstname=@firstname
およびlastame=@lastname
です。
ただし、行の読み取りと更新の間に、他のプロセスによって姓または名の値が変更されました。 WHERE
句の値が列の1つで異なるため、UPDATEは失敗し、更新は@@rowcount==0
をdbmlに返します。これにより、発生したエラーが処理されます。
デザイナーでlinqをsqlスキーマに更新すると、私の問題が解決します
Windows Phone 8でこのエラーが発生していました。そして、問題が何であるかを理解するのに少し時間がかかりました。基本的にはこれでした:
TrackingInformationというクラスがありました。 1.サーバーから更新バージョンを取得しました。 2.私のTileServiceは、その情報でセカンダリタイルを更新し、(!!)1つのプロパティを更新して、電話のローカルデータベースに保存しました。 3.オブジェクトの最初のインスタンスを再度保存しようとすると、「行が見つからないか、変更されていません」というエラーが表示されます。
私にとっては、3番目の部分を削除するだけで、問題なく動作しました(更新されたバージョンですでに保存されています)。しかし、1つのプロパティが変更されたため、例外が発生しました...
EF7がWindows Phoneに登場するまで待ちきれません。WP8の現在のEFで頭痛の種です。