为什么我不能抛出自己的 sql 连接异常?

Why I cannot throw my own sql connection exception?

提问人:Petr 提问时间:1/29/2023 最后编辑:marc_sPetr 更新时间:1/29/2023 访问量:117

问:

我正在尝试创建一个简单的 WPF 应用程序。我希望应用程序指示它是否未连接到数据库,以便它无法发送请求并执行其连接检查。只需抛出并捕获异常,该异常将打印在屏幕上

我的方法:IsConnected

public static bool IsConnected(SqlConnection conn)
{
    bool isConnected = false;

    try
    {
        if (conn == null)
        {
            throw new ConnectionException("It is not possible to connect to the database. Please check your settings and try again");
        }
        else
        {
            isConnected = true;
        }
    }
    catch (ConnectionException ex)
    {
        MessageBox.Show(ex.Message);
    }

    return isConnected;
}

我在哪里使用这种方法:IsConnected()

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

    User user = null;

    try
    {
        using (SqlConnection conn = new SqlConnection(DatabaseSingleton.connString))
        {
            if (DatabaseSingleton.IsConnected(conn))
            {
                using (SqlCommand command = new SqlCommand(query, conn))
                {
                    conn.Open();
                    command.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = email;
                    command.Parameters.Add("@password", SqlDbType.VarChar, 50).Value = password;

                    SqlDataReader reader = command.ExecuteReader();

                    while (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))
                            };
                    }

                    reader.Close();
                }
            }
        }
    }
    catch (InvalidInput e)
    {
        MessageBox.Show(e.Message);
    }

    return user;
}
C# SQL Server 数据库 WPF 异常

评论

0赞 marc_s 1/29/2023
乍一看,代码似乎还不错 - 您看到的问题是什么?正在发生(或没有发生)应该发生的事情是什么??
0赞 Petr 1/29/2023
@marc_s切换后应用程序被冻结(因为我没有连接,所以我想让用户知道他没有连接。这样他就看不到冻结的窗户)
0赞 Andy 1/29/2023
切换是什么意思?也许您应该 ping 而不是尝试连接。数据库不可用是很常见的吗?我
2赞 Andy 1/29/2023
此外,所有数据库访问都应使用异步方法,以避免阻塞 ui 线程。通常会有延迟,但它通常与数据库获取数据和响应有关。你也应该看看 dapper。learndapper.com
1赞 AlwaysLearning 1/29/2023
什么时候会是真的?除非系统内存不足并且无法创建新实例(在这种情况下,它可能会抛出一个 ),否则 将始终为 non-null。它只是尚未连接,因为直到稍后在代码中才会调用。conn == nullSqlConnectionOutOfMemoryExceptionconnconn.Open()

答:

0赞 Andy 1/29/2023 #1

由于数据库访问的工作方式,您的方法本质上是次优的。如果超时,ADO 在任何情况下都应引发错误。

当您尝试与

 SqlConnection conn = new SqlConnection

这将尝试在超时之前连接一个默认时间段。我想那是 30 秒。您可以在连接字符串中覆盖它。

https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.connectiontimeout?view=dotnet-plat-ext-7.0

您最初可以将其设置为 2 秒并减少等待时间。不过,这仍然是 2 秒,也许有一天您的数据库会有点慢。

如果数据库服务器可能可用,也可能不可用,则可以先尝试使用 ping 来查看服务器是否存在并正常工作。

在 c 中使用 ping#

当您尝试对数据库执行任何操作时,都会有延迟。您发送请求。dbms 接收它。去获取您的数据并返回它。

大多数延迟通常归因于数据库服务器上发生的情况。

您应该通过在另一个线程上执行所有数据库访问并返回结果来释放 ui 线程。您应该对所有数据库访问(包括打开数据库)使用异步方法。

例如 OpenAsync

https://learn.microsoft.com/en-us/dotnet/api/system.data.common.dbconnection.openasync?view=net-7.0

使用 async Task 而不是 void 进行数据库访问。

https://www.pluralsight.com/guides/using-task-run-async-await