You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法抛出自定义SQL连接异常?WPF数据库连接问题

问题分析与解决方案

为什么自定义异常无法抛出?

  • 异常被内部捕获,外部无法感知:你的IsConnected方法中,抛出ConnectionException后立刻在方法内部捕获并处理了,这个异常不会传递到调用它的UserLogin方法中,外部根本看不到异常抛出的效果。
  • 触发异常的条件永远不会满足:在UserLogin中,你通过new SqlConnection(DatabaseSingleton.connString)创建连接对象,这个对象永远不会是null,所以IsConnected里的if (conn == null)分支永远不会执行,自然不会抛出异常。
  • 方法逻辑未实现真正的连接检查:当前IsConnected只是判断连接对象是否存在,并没有实际尝试连接数据库,就算连接字符串错误、数据库未启动等真实连接失败的情况,也不会触发任何异常。

修正方案

1. 重构连接检查方法

去掉内部异常捕获,改为真正尝试连接数据库,并在失败时抛出自定义异常:

public static void CheckDatabaseConnection(SqlConnection conn)
{
    if (conn == null)
    {
        throw new ConnectionException("无法连接数据库,请检查配置后重试");
    }

    try
    {
        conn.Open();
        conn.Close();
    }
    catch (SqlException ex)
    {
        // 将系统SQL异常包装为自定义异常抛出
        throw new ConnectionException("数据库连接失败:" + ex.Message, ex);
    }
}

注:方法名改为CheckDatabaseConnection更贴合实际功能,它不再返回布尔值,而是通过异常告知连接状态

2. 修改登录方法的调用逻辑

在调用连接检查方法时,捕获自定义异常并处理:

public User UserLogin(string email, string password)
{
    string query = @"SELECT * FROM [User] WHERE email = @email AND password = @password";
    User user = null;

    try
    {
        using (SqlConnection conn = new SqlConnection(DatabaseSingleton.connString))
        {
            // 先执行连接检查
            DatabaseSingleton.CheckDatabaseConnection(conn);
            
            using (SqlCommand command = new SqlCommand(query, conn))
            {
                command.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = email;
                command.Parameters.Add("@password", SqlDbType.VarChar, 50).Value = password;

                // 用using包裹DataReader,自动释放资源
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    // 邮箱唯一,无需while循环
                    if (reader.Read())
                    {
                        user = new User
                        {
                            Id = reader.GetInt32(0),
                            Name = reader.GetString(1),
                            Second_name = reader.GetString(2),
                            Email = reader.GetString(3),
                            Password = reader.GetString(4),
                            User_type = (Type_Of_User)Enum.ToObject(typeof(Type_Of_User), reader.GetInt32(5))
                        };
                    }
                }
            }
        }
    }
    catch (ConnectionException ex)
    {
        MessageBox.Show(ex.Message);
    }
    catch (InvalidInput e)
    {
        MessageBox.Show(e.Message);
    }
    catch (SqlException ex)
    {
        MessageBox.Show("数据库操作出错:" + ex.Message);
    }

    return user;
}

额外注意事项

自定义异常ConnectionException需确保继承自Exception类:

public class ConnectionException : Exception
{
    public ConnectionException(string message) : base(message) { }
    public ConnectionException(string message, Exception innerException) : base(message, innerException) { }
}

内容的提问来源于stack exchange,提问作者Petr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:41:07