我有以下代码来测试数据库连接,它会定期运行以测试数据库可用性:
private bool CheckDbConn()
{
SqlConnection conn = null;
bool result = true;
try
{
conn = DBConnection.getNewCon();
ConnectionState conState = conn.State;
if (conState == ConnectionState.Closed || conState == ConnectionState.Broken)
{
logger.Warn(LogTopicEnum.Agent, "Connection failed in DB connection test on CheckDBConnection");
return false;
}
}
catch (Exception ex)
{
logger.Warn(LogTopicEnum.Agent, "Error in DB connection test on CheckDBConnection", ex);
return false; // any error is considered as db connection error for now
}
finally
{
try
{
if (conn != null)
{
conn.Close();
}
}
catch (Exception ex)
{
logger.Warn(LogTopicEnum.Agent, "Error closing connection on CheckDBConnection", ex);
result = false;
}
}
return result;
}
和
static public SqlConnection getNewCon()
{
SqlConnection newCon = new SqlConnection();
newCon.ConnectionString = DBConnection.ConnectionString; // m_con.ConnectionString;
newCon.Open();
return newCon;
}
我的问题是:这会按预期工作吗?
具体来说,我关注的是ConnectionState
的测试。状态是否可能是:连接(因为Open()
是同步的)?
在这种情况下我该怎么做?
提前谢谢,Omer
答案 0 :(得分:44)
你可以这样试试。
public bool IsServerConnected()
{
using (var l_oConnection = new SqlConnection(DBConnection.ConnectionString))
{
try
{
l_oConnection.Open();
return true;
}
catch (SqlException)
{
return false;
}
}
}
答案 1 :(得分:11)
SqlConnection
在无法连接到服务器时会抛出SqlException
。
public static class SqlExtensions
{
public static bool IsAvailable(this SqlConnection connection)
{
try
{
connection.Open();
connection.Close();
}
catch(SqlException)
{
return false;
}
return true;
}
}
用法:
using(SqlConnection connection = GetConnection())
{
if(connection.IsAvailable())
{
// Success
}
}
答案 2 :(得分:9)
您的代码似乎很好,但您确实需要使用IDisposable模式和一些命名约定:
private bool CheckDbConnection(string connectionString)
{
try
{
using(var connection = new SqlConnection(connectionString))
{
connection.Open();
return true;
}
}
catch (Exception ex)
{
logger.Warn(LogTopicEnum.Agent, "Error in DB connection test on CheckDBConnection", ex);
return false; // any error is considered as db connection error for now
}
}
并且connection.Close()
不应该抛出。只需使用using
块就可以了。
无需测试Close
状态,因为您刚刚打开它
More about the Broken
state:
已损坏与数据源的连接已断开。这可能发生 仅在连接打开后。此状态下的连接 可以关闭然后重新打开。 (此值保留供将来使用 该产品的版本。)
所以真的,不需要测试它。
如果您处于多线程上下文并且您的连接实例已共享,则Connecting
状态可能会被捕获。但这不是你的情况。
答案 3 :(得分:1)
此代码在调用时不会阻塞 UI。
public static class DatabaseExtensions
{
public static async Task<bool> IsConnectionViable(this string connectionStr)
{
await using var sqlConn = new SqlConnection(connectionStr);
return await sqlConn.IsConnectionViable();
}
public static async Task<bool> IsConnectionViable(this SqlConnection connection)
{
var isConnected = false;
try
{
await connection.OpenAsync();
isConnected = (connection.State == ConnectionState.Open);
}
catch (Exception)
{
// ignored
}
return isConnected;
}
}
答案 4 :(得分:0)
我不能评论......
...也避免捕获常规异常“catch(Exception ex)”并尝试捕获特定异常,如上面的示例“catch(SqlException ex)”
答案 5 :(得分:0)
实际上,在visual studio中,连接类具有sonnectionstate属性。
当连接状态改变时,连接状态改变事件被触发。
您可能想查看这篇文章。
https://msdn.microsoft.com/en-us/library/aa326268(v=vs.71).aspx
答案 6 :(得分:0)
我正在使用@Ramesh Durai的解决方案,但发现我的设置至少(应用程序启动后定期调用/测试;使用带有Sql Server 2012数据库的.Net 3.5)第一次调用{{1}使数据库脱机后返回IsConnected()
。但是,它在下面的true
行中抛出了预期的例外情况:
ExecuteScalar()
答案 7 :(得分:0)
此代码用于Mysql。
public class Program
{
string connection = "SERVER=localhost; user id=root; password=; database=dbname";
private void Form1_Load(object sender, System.EventArgs e)
{
checkifconnected();
}
private void checkifconnected()
{
MySqlConnection connect = new MySqlConnection(connection);
try{
connect.Open();
MessageBox.Show("Database connected");
}
catch
{
MessageBox.Show("you are not connected to database");
}
}
public static void Main()
{
}
}