17

Entity Framework を使用して SQL データにアクセスしています。データベース スキーマにいくつかの制約があり、これらの制約が原因で発生する例外をどのように処理すればよいか考えています。

例として、2 人のユーザーが (ほぼ) 同一のエンティティを同時に DB に追加しようとすると、次の例外が発生します。

System.Data.UpdateException
"An error occurred while updating the entries. See the InnerException for details."

(inner exception) System.Data.SqlClient.SqlException
"Violation of UNIQUE KEY constraint 'Unique_GiftId'. Cannot insert duplicate key in object 'dbo.Donations'.\r\nThe statement has been terminated."

この特定の例外を適切にキャッチするにはどうすればよいですか?

汚い解決策:

    catch (UpdateException ex)
    {
        SqlException innerException = ex.InnerException as SqlException;
        if (innerException != null && innerException.Message.StartsWith("Violation of UNIQUE KEY constraint 'Unique_GiftId'"))
        {
            // handle exception here..
        }
        else
        {
            throw;
        }
    }

このアプローチは機能しますが、いくつかの欠点があります。

  • タイプ セーフなし: コードは、一意の列の名前を含む例外メッセージに依存します。
  • SqlCLient クラスへの依存 (壊れた抽象化)

これに対するより良い解決策を知っていますか?すべてのフィードバックをありがとう..

注:アプリケーション層内で手動で制約をコーディングしたくありません。DB に入れたいのです。

4

3 に答える 3

17

SQL エラー番号 ( SqlException.Number )をトラップできるはずです。

この場合は 2627 で、これは SQL Server でずっと同じです。

抽象化が必要な場合は、データベース エンジンごとに異なる例外番号とメッセージがスローされるため、常にデータベース エンジンに依存することになります。

于 2010-09-12T10:02:03.480 に答える
2

1 つの方法は、内部 SqlExceptionのErrors プロパティを調べることです。SqlError クラスには、正確なエラーを識別するNumber プロパティがあります。すべてのエラー コードの一覧については、master.dbo.sysmessages テーブルを参照してください。

もちろん、これでも SQL Server に結び付けられます。独自の「EF例外アナライザー」をロールする以外に、これを抽象化する方法を知りません。

于 2010-09-12T10:00:12.437 に答える
0

EFを使用する場合、キーを明示的に割り当てることはできないため、このシナリオは発生しないはずです。むしろ、コンテキストが適切なものを割り当てることを許可します。同時実行性の問題がある場合は、トランザクションスコープで更新を行う必要があります。

次に、UpdateExceptionがある場合は、更新を再試行できます。これはトランザクションスコープで安全に実行でき、更新が完了したときにのみスコープを完了できます。このシナリオでは、次回更新が行われる可能性は、最初の更新よりも大きくなります。

于 2012-05-10T19:26:13.570 に答える