在c#查询尝试中抛出异常的最佳方式

本文关键字:抛出异常 最佳 方式 查询 | 更新日期: 2023-09-27 18:14:15

嗨,我正在使用c#和实体框架(linq to entities)开发一个winform应用程序。假设以下场景:

在某个类的方法中,我以value

的形式设置了一个值的对象
 private void agrega_cliente_Click(object sender, EventArgs e)
 {
        cliente = new _Cliente();
        try
        {
            cliente.nombres = nom_cliente.Text;
            cliente.apellidoP = apellidoP_cliente.Text;
            cliente.apellidoM = apellidoM_cliente.Text;
            cliente.fechaNacimiento = fechaNacimientoPicker.Value.Date;
            if (operaciones.AgregaCliente(cliente, referencias))
            {
                MessageBox.Show("Cliente Agregado");
                this.Close();
            }
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
 }

注意,对方法"AgregaCliente"的赋值和调用是在try和catch之间的,所以如果触发了异常,MessageBox将显示它。

然后在其他类中,我有AgregaCliente方法在数据库中插入值。

 public bool AgregaCliente(_Cliente cliente, ArrayList refes)
 {
        try
        {
            Cliente cli = new Cliente()
            {
                Nombres = cliente.nombres,
                ApellidoP = cliente.apellidoP,
                ApellidoM = cliente.apellidoM,
                FechaNac = cliente.fechaNacimiento
            };
            if (NombreExiste(cli))
                context.clientes.AddObject(cli);
            else
                throw new System.ArgumentException("El usuario ya existe");
            if (refes.Count != 0)
            {
                foreach (_Referencia elem in refes)
                    context.referencias_personales.AddObject(AgregaReferencia(elem));
            }
            context.SaveChanges();
        }
        catch (Exception ex)
        {
            return false;
        }
        return true;
 }

在这个方法内部,有一个对"NombreExiste()"的调用,检查用户是否已经插入,如果用户存在,则抛出异常。

所以这里的问题是,如果在"AgregaCliente"方法中抛出一个异常,我希望这个异常被"agrega_cliente_Click()"方法捕获,这样用户就知道是什么引起了这个问题。我希望你能理解我在做什么。

谢谢

在c#查询尝试中抛出异常的最佳方式

只要在AgregaCliente()方法中去掉try/catch,异常就会自动冒出来。

public bool AgregaCliente(_Cliente cliente, ArrayList refes) 
{ 
    Cliente cli = new Cliente() 
    { 
        Nombres = cliente.nombres, 
        ApellidoP = cliente.apellidoP, 
        ApellidoM = cliente.apellidoM, 
        FechaNac = cliente.fechaNacimiento 
    }; 
    if (NombreExiste(cli)) 
        context.clientes.AddObject(cli); 
    else 
        throw new System.ArgumentException("El usuario ya existe"); 
    if (refes.Count != 0) 
    { 
        foreach (_Referencia elem in refes) 
            context.referencias_personales.AddObject(AgregaReferencia(elem)); 
    } 
    context.SaveChanges(); 
    return true; 
} 

问题是您的AgregaCliente()方法正在捕获所有异常并简单地吞下它们。而不是通过:

捕获所有异常
    catch (Exception ex)
    {
        return false;
    }

你应该只捕获特定的你可以处理的异常,而让其他的通过调用链。然而,您应该知道抛出异常对于程序来说是非常"昂贵"的。当抛出异常时,c#在幕后做了很多工作。更好的解决方案可能是使用返回代码向AgregaCliente()方法的调用者指示状态。例如:

public enum AgregaClienteStatus
{
  Success = 0;
  ClientAlreadyExists = 1;
  Other = ??;  // Any other status numbers you want
}
 public AgregaClienteStatus AgregaCliente(_Cliente cliente, ArrayList refes)
 {
            Cliente cli = new Cliente()
            {
                Nombres = cliente.nombres,
                ApellidoP = cliente.apellidoP,
                ApellidoM = cliente.apellidoM,
                FechaNac = cliente.fechaNacimiento
            };
            if (NombreExiste(cli))
                context.clientes.AddObject(cli);
            else
                return AgregaClienteStatus.ClientAlreadyExists
            if (refes.Count != 0)
            {
                foreach (_Referencia elem in refes)
                    context.referencias_personales.AddObject(AgregaReferencia(elem));
            }
            context.SaveChanges();

        return AgregaClientStatus.Success;
 }

当然,如果您不喜欢枚举,也可以使用常数整数来实现此功能。

然后,您可以使用该返回状态向用户指示信息,而不会产生异常:

  var result = AgregaClient(cliente, refes);
  switch (result)
  {
    case AgregaClientStatus.Success:
         // Perform success logic
         break;
    case AgregaClientStatus.ClientAlreadyExists:
         MessageBox.Show("Client already exists");
         break;
    // OTHER SPECIAL CASES
    default:
         break;
   }

}