2010-10-19 29 views
22

Estoy tratando de detectar la excepción lanzada cuando inserto un usuario ya existente con el nombre de usuario dado en mi base de datos. Como dice el título, entonces estoy usando EF. La única excepción que se produce cuando trato de insertar el usuario en db es una "UpdateException": ¿cómo puedo extraer esta excepción para identificar si es una excepción duplicada o algo más?¿Excepción de clave duplicada de Entity Framework?

+0

como con cualquier excepción, un vistazo a la InnerException para averiguar los detalles del error exactas. – RPM1984

Respuesta

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

poner el número correcto en ?????? que corresponde a la única violación de restricción (no sé que desde lo alto de la cabeza).

+0

Perfecto :) - Sin embargo ... Intenté atrapar el Código de Error y dice que el código de error para una entrada duplicada es -2146232060, lo cual me parece un poco extraño. – ebb

+0

Mi mal ... usé errorCódigo en su lugar. Gracias :) – ebb

+9

Para referencia futura: [2601] (http://msdn.microsoft.com/en-us/library/aa258747 (v = sql.80) .aspx) es una violación de restricción única (para SQL Server). – kamranicus

11

Ahora en C# 6.0, debe ser capaz de hacer algo como esto:

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

porque estoy usando ADO.NET Entity Framework con C#, tuve que hacer un pequeño cambio en esto - creo que sirve a nadie .. .

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

mi problema se produjo porque necesitaba DbUpdateException en lugar de UpdateException, y mi objetivo InnerException tenía un objeto InnerException adicional que contenía el número que necesitaba ...

+0

Gracias, esto fue útil. Voy a usar esto, pero con un cheque nulo adicional en la línea 7; tal como está escrito, el bloque catch lanzará una NullReferenceException si ex.InnerException (es decir, la primera InnerException anidada) es nula. –

0

Creo que es mejor si evita que ocurra la excepción. Si es posible con su código, haría lo siguiente:

Al usar el marco de entidad, lo mejor que puede hacer es primero intentar y obtener la entrada que le causará el problema, con SingleOrDefault de LINQ. Ahora puede actualizar la entidad obtenida con la instancia que desea insertar, le proporciona un número de ID con autoincremento si lo usa. Si SingleOrDefault es nulo, puede agregar su entidad de forma segura.

ejemplo de código:

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); 
    } 
Cuestiones relacionadas