3

最近、LINQ の実装を開始するために LINQ について調べていましたが、UPDATE クエリを生成する方法に関して特に気になる点があります。

SQLMetal またはオブジェクト リレーショナル デザイナーを使用してエンティティ コードを自動的に作成すると、明らかにすべてのテーブルのすべてのフィールドが属性UpdateCheck.Alwaysを取得します。つまり、UPDATE および DELETE クエリごとに、次のような SQL ステートメントが取得されます。

UPDATE table SET a = 'a' WHERE a='x' AND b='x' ... AND z='x', ad infinitum

さて、私を純粋主義者と呼んでください。しかし、これは私には非常に非効率的であり、非効率的ではなかったとしても、とにかく悪い考えのように感じます. クラスター化された主キーによってフェッチが行われることはわかっているため、遅くはありませんが、SQL はその後もすべてのフィールドをチェックして一致することを確認する必要があります。

確かに、いくつかの非常に機密性の高いアプリケーションでは、このようなものが便利な場合がありますが、典型的な Web アプリケーション (スタック オーバーフローを考えてください) では、 UpdateCheck.WhenChanged がより適切なデフォルトのように思わます LINQ は、すべてのフィールドではなく、変更された実際のフィールドのみを更新します。ほとんどの場合、何かを編集した 2 番目の人がとにかく勝ちます。

つまり、2 人が同じ行の同じフィールドを、その行を読み取ってから UPDATE を起動するまでのわずかな時間内に編集できた場合、見つかった競合は起動されないということです。しかし、実際には非常にまれなケースです。2 人のユーザーが同じものを変更した場合に注意したいことの 1 つは、これに引っかからないようにすることです。これは、2 人がまったく同時に [送信] をクリックすることはないため、2 番目の DataContext の時点で競合が発生しないためです。レコードを読み取って更新します (ページが表示されているときに DataContext を開いたままにして Session に保存したり、そのような他の重大な悪い考えがない限り)。

ただし、まれなケースですが、これが発生した場合に、コードで時々例外が発生しないようにしたいと考えています。

だから私の最初の質問は、これを信じるのは間違っていますか? (繰り返しになりますが、銀行アプリケーションではなく、「典型的な」Web アプリケーションの場合) UpdateCheck.Always をデフォルトとして使用することが賢明な考えである理由がわかりませんか?

2 番目の質問は、これを文明的に変更できるかどうかです。SQLMetal または ORD にどの UpdateCheck 属性を設定するかを伝える方法はありますか?
いくつかの正規表現を使用してファイル内のすべての属性を直接編集する必要があるツールを実行することを忘れないようにしなければならない状況を回避しようとしています。 DB の更新後に SQLMetal を実行すると、このツールを実行しなくなり、すべてのコードが非常に微妙な方法で壊れます。これは、開発環境でのテストではおそらく見つからないでしょう。

助言がありますか?
戦争の話は大歓迎です。これに関する他の人の経験から学びたいです。

どうもありがとうございました!

4

1 に答える 1

2

さて、最初の質問に答えるために-私はあなたに同意します。私はこの「組み込み」の楽観的並行性の大ファンではありません。特に、更新が発生した後に同じであることが保証されていないタイムスタンプ列またはフィールドがある場合はそうです。

2番目の質問に対処するために-SqlMetalのデフォルトのアプローチ(UpdateCheck = Always)をオーバーライドする方法がわからないため、適切な列に対してUpdateCheck=Neverを設定するツールを作成することになりました。バッチファイルを使用してSqlMetalを呼び出し、その後ツールを実行しています)。

ああ、私はそれを考えていますが、SqlMetalが関係をモデル化して、「Delete OnNull」ではなくnullに外部キーを設定することもわかりました(特に結合テーブルの場合)。これらも適切に設定するには、同じ生成後ツールを使用する必要がありました。

于 2009-03-26T14:11:27.400 に答える