-1

I'm trying to create a simple WPF application. I would like the application to indicate if it is not connected to the database, so that it cannot send requests and perform a check of its connection. Simply throw and catch the exception, which will be printed on the screen

My IsConnected method:

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

Where I am using this IsConnected() method:

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;
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Petr
  • 103
  • 6
  • Code seems quite OK at first glance - what's the problem you're seeing ? What is happening (or not happening) that should be happening?? – marc_s Jan 29 '23 at 09:42
  • @marc_s after switching the app is frozen(because I am not connected, so I want to let the user know that he is not connected. So that he doesn't see just frozen windows) – Petr Jan 29 '23 at 09:49
  • What do you mean by switching? Maybe you should ping rather than try to connect. Will it be common for the database to be unavailable? I – Andy Jan 29 '23 at 10:03
  • @Andy I meant click the button, sorry. The database will be accessible if the configuration is correct to connect to. Simply, I don't want the user to see a frozen application. I want to let him know where the error is – Petr Jan 29 '23 at 10:11
  • Let's put this another way. A connection will try for n seconds before timing out. Ping takes milliseconds. Therefore. You should ping and see if the server is up and responds. Unless there is some other aspect to this means you cannot ping. – Andy Jan 29 '23 at 10:24
  • 2
    Additionally, all database access should use async approach to avoid blocking the ui thread. There's often latency but it's usually associated with the database getting data and responding. You should look into dapper as well. https://www.learndapper.com/ – Andy Jan 29 '23 at 10:26
  • When a library captures an exception, unless the library contains a THROW, you cannot capture the exception again. – jdweng Jan 29 '23 at 10:38
  • 1
    When would `conn == null` ever be true? Unless the system is out of memory and can't create a new `SqlConnection` instance (in which case it will probably throw an `OutOfMemoryException`) `conn` will always be not-null. It just won't be connected yet because `conn.Open()` isn't called until later in your code. – AlwaysLearning Jan 29 '23 at 10:40
  • If it fails it should error anyhow and if (DatabaseSingleton.IsConnected(conn)) will return false so it'll drop through. But it's not an ideal approach to database access: synchronous on the ui thread. – Andy Jan 29 '23 at 10:49

1 Answers1

0

Your approach is inherently sub optimal due to the way database access works. ADO should in any case throw an error if it times out.

When you try and connect with

 SqlConnection conn = new SqlConnection

That will try and connect for a default period before it times out. I think that's 30 seconds. You may over ride that in your connection string.

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

You could initially set that to say 2 seconds and reduce the wait. That's still 2 seconds though and maybe your database will be a bit slow one day.

If a database server may or may not be available then you can first try using ping to see if the server is there and working.

Using ping in c#

When you try and do anything with a database there will be a latency. You send a request off. The dbms receives it. goes and gets your data and returns it.

Most of the latency is usually down to things happening on the database server.

You should free up your ui thread by doing all database access on another thread and returning the results. You should use async methods for all db access including opening the database.

eg OpenAsync

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

Rather than voids use async Task for your database access.

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

Andy
  • 11,864
  • 2
  • 17
  • 20