web-dev-qa-db-ja.com

Entity Frameworkからの重複キーの例外?

指定されたユーザー名を持つ既存のユーザーをデータベースに挿入したときにスローされる例外をキャッチしようとしています。タイトルが言うように、私はEFを使用しています。ユーザーをdbに挿入しようとしたときにスローされる唯一の例外は、「UpdateException」です。この例外を抽出して、重複する例外か他の何かかを識別するにはどうすればよいですか。

28
ebb
catch (UpdateException ex)
{
    SqlException innerException = ex.InnerException as SqlException;
    if (innerException != null && innerException.Number == ??????)
    {
        // handle exception here..
    }
    else
    {
        throw;
    }
}

正しい数字を??????これは固有の制約違反に対応します(頭のてっぺんからはわかりません)。

38
Darin Dimitrov

私は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オブジェクトがあったために発生しました...

14
Musical Coder

C#6.0では、次のようなことができるはずです。

catch (UpdateException ex) when ((ex.InnerException as SqlException)?.Number == ??????)
{
    // Handle exception here
}
13
peteski

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))
{

}
3
Sam

例外が発生しないようにした方がいいと思います。あなたのコードで可能であれば、私は次のことをします:

エンティティフレームワークを使用する場合、最善の方法は、最初に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);
    }
1
FireStormHR