为何无法抛出自定义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
相关产品推荐
相关产品推荐

