-2

国という名前のテーブルがあり、sql servwer 2008 r2 で「一意のキー」タイプの「インデックス/キー」を作成して、country_name フィールドを一意に定義します。しかし現在、ユーザーが私の asp.net mvc3 アプリケーションに既に存在する country_name 値を挿入すると、タイプ「System.Data.Entity.Infrastructure.DbUpdateException」の例外が発生します。これは非常に一般的です。

一意の制約に違反した場合に備えて、特定の例外を定義する方法はありますか??? 一般的な「System.Data.Entity.Infrastructure.DbUpdateException」例外を発生させるだけではなく?

ブラジル

4

1 に答える 1

2

おそらく、現時点ではテストできないと思いますが、の内部例外は、DbUpdateExceptionおそらく重複または外部キー制約に関する例外です。さらに重要なことは、国が既に存在するかどうかを確認することで、例外をスローしない機会があることです。私が考えることができる2つの方法は次のとおりです。単純な選択を実行して国が既に存在するかどうかを確認し、存在しない場合は、挿入/追加を実行するか、ストアドプロシージャを記述して、選択/挿入またはマージを実行し、必要な値を返します.

アップデート

(これは、イベントのロジック フローを示すためのサンプル コードであり、特にすべての例外をキャッチすることにより、適切なプログラミング手法ではありません)

例外ロジック

public AddCountry(string countryTitle)
{
  using (var db = new DbContext(_connectionString)
  {
    try
    {
      // Linq to (SQL/EF)-ish code
      Country country = new Country();
      country.ID = Guid.NewGuid();
      country.Title = countryTitle;
      db.Countrys.Add(country);
      db.SubmitChanges(); // <--- at this point a country could already exist
    }
    catch (DbUpdateException ex)
    {
      // <--- at this point a country could be delete by another user
      throw Exception("Country with that name already exists");
    }
  }
}

非例外ロジック

public AddCountry(string countryTitle)
{
  using (var db = new DbContext(_connectionString)
  {
    using (TransactionScope transaction = new TransactionScope())
    {
      try
      {
        Country country = db.Countries 
                            .FirstOrDefault(x => x.Title = countryTitle);

        if (country == null)
        {
          country = new Country();
          country.ID = Guid.NewGuid();
          country.Title = countryTitle;
          db.Countrys.Add(country);
          db.SubmitChanges(); // <--- at this point a country 
                              // shouldn't exist due to the transaction
                              // although someone with more expertise
                              // on transactions with entity framework
                              // would show how to use transactions properly
        }
      }
      catch (<someTimeOfTransactionException> ex)
      {
        // <--- at this point a country with the same name
        // should not exist due to the transaction
        // this should really only be a deadlock exception
        // or an exception outside the scope of the question
        // (like connection to sql lost, etc)
        throw Exception("Deadlock exception, cannot create country.");
      }
    }
  }
}

ほとんどの場合、TransactionScope(Transaction transactionToUse) コンストラクターが必要であり、適切に構成されます。 おそらく、Transactions.IsolationLevel が Serializable に設定されている

Entity Framework transactionも読むことをお勧めします。

于 2012-04-21T02:30:26.820 に答える