2010-10-19 4 views
22

J'essaye d'attraper l'exception levée quand j'insère un utilisateur déjà existant avec le nom d'utilisateur donné dans ma base de données. Comme le titre l'indique, j'utilise EF. La seule exception qui est lancée lorsque j'essaie d'insérer l'utilisateur dans db est une "UpdateException" - Comment puis-je extraire cette exception pour identifier si c'est une exception en double ou autre chose?Exception de clé en double d'Entity Framework?

+0

comme toute exception, regardez les InnerException pour connaître les détails de l'erreur exacte. – RPM1984

Répondre

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

Mettre le nombre correct à ?????? qui correspond à une violation de contrainte unique (je ne sais pas à partir du haut de ma tête).

+0

Parfait :) - Cependant .. J'ai juste essayé d'attraper le ErrorCode et il dit que le code d'erreur pour une entrée en double est -2146232060 qui me semble un peu étrange? – ebb

+0

Mon mauvais .. utilisé errorCode à la place. Merci :) – ebb

+9

Pour référence future: [2601] (http://msdn.microsoft.com/en-us/library/aa258747 (v = sql.80) .aspx) est une violation de contrainte unique (pour SQL Server). – kamranicus

11

maintenant en C# 6.0, vous devriez être en mesure de faire quelque chose comme ceci:

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

Parce que j'utilise EntityFramework avec C#, je devais faire un changement mineur à cette question - espérons que cela aide tout le monde .. .

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; 
    } 
} 

mon problème était dû au fait que je avais besoin DbUpdateException au lieu de UpdateException, et mon objet InnerException avait un objet InnerException supplémentaire qui contenait le numéro que je avais besoin ...

+0

Merci, ceci a été utile! Je vais l'utiliser, mais avec un contrôle nul supplémentaire sur la ligne 7; tel qu'écrit, le bloc catch lancera une exception NullReferenceException si ex.InnerException (c'est-à-dire la première InnerException imbriquée) est null. –

0

Je pense que c'est mieux si vous empêchez l'exception de se produire. Si possible avec votre code, je ferais ce qui suit:

Lorsque vous utilisez framework d'entité, la meilleure chose à faire est d'essayer d'abord d'obtenir l'entrée qui vous causera le problème, avec SingleOrDefault de LINQ. Maintenant, vous pouvez mettre à jour l'entité obtenue avec l'instance que vous vouliez insérer, vous garantissant un numéro d'identification avec auto-incrémentation si vous l'utilisez. Si SingleOrDefault est null, vous pouvez ajouter votre entité en toute sécurité.

exemple de code:

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); 
    } 
Questions connexes