73

I have an app that connects to a MYSQL database through the entity framework. It works 100% perfectly, but I would like to add a small piece of code that will test the connection to the database upon app startup.

I had the idea of simply running a tiny command to the database and catching any exceptions, however if there is a problem (eg App.Config missing or Database server down) the app takes a huge amount of time to run this code and then throw the exception (~1 min). I imagine this is due to connection timeouts etc but I have fiddled with such properties to no avail.

Would anyone be able to assist with any ideas as to where to go?

2
  • one thing would be to ping the server to check if it is up. Commented Oct 6, 2013 at 16:27
  • public PingReply Send( string hostNameOrAddress ) msdn.microsoft.com/en-us/library/7hzczzed.aspx Commented Oct 6, 2013 at 16:31

8 Answers 8

60

Are you just wanting to see if the DB connection is valid? If so take a look at the

using (DatabaseContext dbContext = new DatabaseContext())
{
     dbContext.Database.Exists();
}

http://msdn.microsoft.com/en-us/library/gg696617(v=vs.103).aspx

and for checking if a server machine is up, DB server or web services server , try this:

public PingReply Send( string hostNameOrAddress )

http://msdn.microsoft.com/en-us/library/7hzczzed.aspx

Sign up to request clarification or add additional context in comments.

7 Comments

I tested this by taking a db 'offline' in SQL Server and Database.Exists() still returned true. Something to watch out for...
The best way is to use the mysql dll conector and do it manually. If you use migrations it will return false, but the connection is OK!
This is not working for MS SQL, Exists return true and DBSet.Load give exception at the same time.
What is the Exception?
'I believe the above solution is for an EF version earlier than EF6' Indeed, EF6 was not around when the answer was posted. Thanks for posting details, I shall review and update the answer if required.
|
60

The solution as @Danilo Breda pointed out is to call the DbContext.Database.Connection.Open()

It is tested with EF6.

My implementaion:

    public static bool CheckConnection()
    {
        try
        {
            MyContext.Database.Connection.Open();
            MyContext.Database.Connection.Close();
        }
        catch(SqlException)
        {
            return false;
        }
        return true;
    }

5 Comments

I like this solution the most, and yes, you should not use exceptions for flow logic (usually ;-) )
I would add this to the Unit Tests.
I understand that if I want to ensure that the MySQL server is up on each interaction witht the DB, I need to do if (CheckConnection()) {..} for every single action (In order to avoid application errors in case the MySQL server is down). Any idea how to implement this check on more global level? So there would be no need to call and re-call CheckConnection() ?
@W.M. The best choice for would be to implement connection resiliency, see the following article. codeproject.com/Tips/758469/…
This was not good for me. It just returns always ok reaching a network db even if I phisically unplug my network cable. To make it work I had to read a connection property, like ServerVersion, like this: Dim serverversion As String = dbBIZ.Database.Connection.ServerVersion (did it between open and close tag, of course) In this way it tries to get the sql server version and fails if db connection is KO.
41

In EntityFramework Core you can simply call: Database.CanConnect();.

(using EF Core 2.2.1)

Summary: Determines whether or not the database is available and can be connected to.

Note that being able to connect to the database does not mean that it is up-to-date with regard to schema creation, etc.

4 Comments

Also be aware that CanConnect doesn't return false when the database server is offline, it throws an exception
@MarianoSoto are you sure? The docs say, "Any exceptions thrown when attempting to connect are caught and not propagated to the application."
It was true back then: github.com/dotnet/efcore/issues/18355. Maybe now it works differently
It was fixed in ef core 5.0 github.com/dotnet/efcore/pull/18867
13

I use this code for my project:

private bool TestConnectionEF()
{
    using (var db = new SistemaContext())
    {
        db.Database.Connection.Open();

        if (db.Database.Connection.State == ConnectionState.Open)
        {
            Console.WriteLine(@"INFO: ConnectionString: " + db.Database.Connection.ConnectionString 
                     + "\n DataBase: " + db.Database.Connection.Database 
                     + "\n DataSource: " + db.Database.Connection.DataSource 
                     + "\n ServerVersion: " + db.Database.Connection.ServerVersion 
                     + "\n TimeOut: " + db.Database.Connection.ConnectionTimeout);

            db.Database.Connection.Close();

            return true;
        }

        return false;
    }
}

7 Comments

Given your use of using block, is the connection.close() necessary?
@ComeIn If your Context class have a databaseconnectionclose on the dispose method, you can take it off.. i dont know if the ORM do it. For me when i open a connection, i need to closeit.If i dont open, i dont need to close.
EF will close the underlying DBContext. Best not to do this manually unless necessary. see: stackoverflow.com/questions/28067150/…
@ComeIn EF will close if it opens for me, on my code i open it manually so i need to close it ("If you open a connection manually, EF will NOT close it for you after a database operation is completed.")
Then I guess we circle back to my original question. Do you really need to call Connection.Open() explicitly, and if not then just remove that call. It is the recommended usage, but of course if you want the extra headache of managing DB connections manually then carry on as you are.
|
9

I know this is an old question, but here is my answer for anyone looking for a newer implementation.

I was able to use CanConnect to check the status of the database:

_database.Database.CanConnect();

# Async too
await _database.Database.CanConnectAsync(_cancellationTokenSource.Token);

I hope this helps others as well. Cheers!

Comments

1

I used the answer from @Sandor and did an extension method to use with EntityFramework Core.

Here's the code:

using Microsoft.EntityFrameworkCore;
using System.Data.Common;

namespace TerminalInventory
{
    public static class ExtensionMethods
    {
        public static bool TestConnection(this DbContext context)
        {
            DbConnection conn = context.Database.GetDbConnection();

            try
            {
                conn.Open();   // Check the database connection

                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

Now you just have to call:

if (!context.TestConnection())
{
    logger.LogInformation("No database connection. Check the connection string in settings.json. {0}", configuration["connectionString"]);

    return;
}

2 Comments

Since you are not inside a using block, shouldn't you close the connection after calling open() to avoid needlessly leaving the connection open?
do you need to close the connection? or is it ok to leave it open?
0

To verify Server and Database connection in Entity Framework, You can use the object Database with its ExecuteSql method. Here a function that returns true of false:

  public bool it_pg_DatabaseConnectionCheck()
  {
    bool Ok ;
    try { 
      int N = _context.Database.ExecuteSql($"SELECT COUNT(*) FROM AnyTableName");
      Ok= true;
    }
    catch (Exception ex) 
    {
      Ok= false;
    }
    return Ok ;
}

where:

  • AnyTableName is the name of any table inside the database you want to verify
  • _context is the class (derived by DbContext as usual) you use in EF

Remarks: mandatory use of dollar sign ($) in front of the sql command string.

This approach have some advantages:

  • no needs to take care of the underlying database type
  • no needs to create manually objects like SqlCommand or other kinds

Comments

-1

I am using the following code for MS SQL connection. Maybe, it will be useful for MySQL too. You don’t even need to use an EF or EF Core.

    public bool IsDbConnectionOK()
    {
        SqlConnectionStringBuilder conStr = new SqlConnectionStringBuilder
        {
            DataSource = ButtonServerName.Text,  // <-- My Form Elements
            InitialCatalog = ButtonDBName.Text, // <-- My Form Elements
            UserID = EditUserName.Text, // <-- My Form Elements
            Password = EditPassword.Text, // <-- My Form Elements
            IntegratedSecurity = false,
            ConnectTimeout = 30
        };

        string connectionstring = conStr.ToString();

        try
        {
            using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionstring))
            {
                connection.Open();
                return true;
            }
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            MessageBox.Show(ex.Message + Environment.NewLine +
                "Error line: " + ex.LineNumber + Environment.NewLine +
                "Procedure name: " + ex.Procedure);
            return false;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return false;
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.