4

http://geekswithblogs.net/michelotti/archive/2007/12/17/117791.aspx

私は C# で ASP.NET を使用しており、linq to sql を使用して、上記のリンク先のブログに示されているようにデータ コンテキストを更新しようとしています。記載されているとおりにテーブルにタイムスタンプ フィールドを作成し、次の方法を使用しています。

private void updateRecord(TableName updatedRecord)
{
 context db = new context();
 db.TableName.Attach(updatedRecord,true);
 db.SubmitChanges();
}

私の質問は、データ コンテキストで Attach メソッドを呼び出そうとする前に、updatedRecord の何かに timeStamp フィールドを割り当てるべきですか?

このコードを実行すると、次の例外が発生System.Data.Linq.ChangeConflictException: Row not found or changed. します。オブジェクトをこの update メソッドに渡す前に、更新しているレコードの主キーを含むすべてのフィールドを更新します。デバッグ中に、オブジェクトの TimeStamp 属性が null として表示されます。そうあるべきかどうかはわかりません。

私が持っているすべての本とリソースは、これがそれを行う方法であると述べていますが、この TimeStamp 属性について詳しく説明しているものはありません。

簡単で分かりやすいので、ご存知の方がいらっしゃいましたら教えてください。

4

2 に答える 2

3

テーブルにタイムスタンプフィールドを作成したとのことなので、後からこの列を追加した場合、列のプロパティが正しく設定されていないのではないでしょうか。DBML デザイナーで TimeStamp 列のプロパティを確認することをお勧めします。次のことを確認してください。

AutoGenerated = true
Auto-Sync = Always
Time Stamp = True
Update Check = Never

サーバーのデータ型はrowversion NOT NULL

自動生成され、常に同期されるように設定されていない場合、挿入が完了したときに行バージョンを変更していないため、行バージョンは挿入から返されません。この値はデータベースによって生成されますが、適切に処理できるように、DataContext はこれを認識する必要があります。

さらに、タイムスタンプ列ができたので、他のすべての列に対して をUpdateCheck設定する必要があります。Never

于 2008-11-07T21:44:03.897 に答える
1

タイムスタンプ列がある場合、(バニラ オブジェクトから) レコードを更新するには: はい、それを割り当てる必要があると思います。そうしないと、オプティミスティック コンカレンシー チェックにタイムスタンプを使用できなくなります。

(切断された)オブジェクトを取得したときにタイムスタンプのコピーを取得し、更新時にこの列を使用して、他の誰も行を編集していないことを確認できます。

2 つの一般的なシナリオがあります。

1: 短期間の操作のみを実行している場合は、最初にデータベースからレコードを取得します。オブジェクトに変更を加え、単純に SumbitChanges() [すべて同じデータ コンテキストで] を行います。データ コンテキストが同時実行を処理します。

2: オブジェクトを切断する場合 (たとえば、しばらくクライアント アプリケーションに渡す場合) は、シリアル化のようなものを使用します (LINQ-to-SQL オブジェクトは DataContractSerializer をサポートします (オプションで、有効にする必要があります))。したがって、サーバーでオブジェクトをシリアル化し、それをクライアントに渡します。クライアントはコピーを変更して、それを返します。サーバーはそれを逆シリアル化し、Attach() と SubmitChanges() を使用します。メモリ内のレコードには、データベースから抽出されたときのタイムスタンプが残っている必要があるため、レコードが切断されている間は常に楽観的同時実行を実行できます。

于 2008-11-07T20:44:06.937 に答える