指定されたユーザー名を持つ既存のユーザーをデータベースに挿入したときにスローされる例外をキャッチしようとしています。タイトルが言うように、私はEFを使用しています。ユーザーをdbに挿入しようとしたときにスローされる唯一の例外は、「UpdateException」です。この例外を抽出して、重複する例外か他の何かかを識別するにはどうすればよいですか。
catch (UpdateException ex)
{
SqlException innerException = ex.InnerException as SqlException;
if (innerException != null && innerException.Number == ??????)
{
// handle exception here..
}
else
{
throw;
}
}
正しい数字を??????
これは固有の制約違反に対応します(頭のてっぺんからはわかりません)。
私はC#でEntityFrameworkを使用しているので、これに小さな変更を加える必要がありました-それが誰かに役立つことを願っています...
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.InnerException.InnerException as SqlException;
if (innerException != null && (innerException.Number == 2627 || innerException.Number == 2601))
{
//your handling stuff
}
else
{
throw;
}
}
私の問題は、UpdateExceptionの代わりにDbUpdateExceptionが必要で、InnerExceptionオブジェクトに、必要な数を含む追加のInnerExceptionオブジェクトがあったために発生しました...
C#6.0では、次のようなことができるはずです。
catch (UpdateException ex) when ((ex.InnerException as SqlException)?.Number == ??????)
{
// Handle exception here
}
C#7では、is演算子を使用できます
// 2627 is unique constraint (includes primary key), 2601 is unique index
catch (UpdateException ex) when (ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601))
{
}
例外が発生しないようにした方がいいと思います。あなたのコードで可能であれば、私は次のことをします:
エンティティフレームワークを使用する場合、最善の方法は、最初にLINQのSingleOrDefaultを使用して、問題の原因となるエントリを取得することです。これで、取得したエンティティを挿入したいインスタンスで更新でき、ID番号を使用する場合は、自動インクリメントで保護されます。 SingleOrDefaultがnullの場合、エンティティを安全に追加できます。
コードの例:
public override void AddOrUpdate(CustomCaseSearchCriteria entity)
{
var duplicateEntityCheck = GetSingleByUniqueConstraint(entity.UserCode, entity.FilterName);
if (duplicateEntityCheck != null)
{
duplicateEntityCheck.Overwrite(entity);
base.Update(duplicateEntityCheck);
}
else
base.Add(entity);
}
public virtual CustomCaseSearchCriteria GetSingleByUniqueConstraint(string userCode, string filterName)
{
return GetAllInternal().SingleOrDefault(sc => sc.UserCode == userCode && sc.FilterName == filterName);
}