创建新的EntityCollection对象时,在尝试对该集合执行某些操作之前,连接不会尝试打开数据库。我需要确定实体集合是否具有有效连接,我找不到有效的方法。
目前我的代码中已经有了这个:
var db = new MyEntityCollection();
try
{
var checkworking = from c in db.Customers select c;
}
catch
{
ConnectToBackUp();
}
这不仅是可怕的代码,而且非常慢,因为它等待一个年龄来确定连接是否在激活之前是否有效。
我知道我可以通过使用ConnectionTimeout来控制放弃之前等待的时间,但这只是另一个丑恶的黑客行为,会让情况变得更糟。
当然有更好的方法吗?
答案 0 :(得分:31)
最简单的:
private bool TestConnection()
{
var db = new MyEntityCollection();
int oldTimeOut = db.CommandTimeout;
try
{
db.CommandTimeout = 1;
db.Connection.Open(); // check the database connection
return true;
}
catch
{
return false;
}
finally
{
db.CommandTimeout = oldTimeOut;
}
}
更新EF6:
using System.Data.Common;
...
public bool TestConnection() {
using (var db = new MyEntityCollection()) {
DbConnection conn = db.Database.Connection;
try {
conn.Open(); // check the database connection
return true;
}
catch {
return false;
}
}
}
答案 1 :(得分:11)
您是否只想查看数据库连接是否有效。如果是这样,请查看objectcontext.databaseExists()
。
答案 2 :(得分:8)
通过绕过房屋并构建一个新的连接字符串以使用ADO进行测试来解决这个问题。仍然需要使用try catch,但速度要快得多:
private bool TestConnection()
{
EntityConnectionStringBuilder b = new EntityConnectionStringBuilder();
ConnectionStringSettings entityConString = ConfigurationManager.ConnectionStrings["MyEntityConnectionString"];
b.ConnectionString = entityConString.ConnectionString;
string providerConnectionString = b.ProviderConnectionString;
SqlConnectionStringBuilder conStringBuilder = new SqlConnectionStringBuilder();
conStringBuilder.ConnectionString = providerConnectionString;
conStringBuilder.ConnectTimeout = 1;
string constr = conStringBuilder.ConnectionString;
using (SqlConnection conn = new SqlConnection(constr))
{
try
{
conn.Open();
return true;
}
catch
{
return false;
}
}
}
答案 3 :(得分:1)
网络或数据库服务器层不应提供此类基础设施吗?手动处理与备份服务器的连接看起来很奇怪。此外,无法等待超时,因为您必须首先尝试打开与主服务器的连接。
ObjectContext.Connection
可以访问连接本身。此属性应返回EntityConnection
实例,该实例包含与真实数据库保持连接的StoreConnection
属性。您可以检查此连接的状态。
答案 4 :(得分:0)
在我的应用中,用户可以从UI更改与数据库的连接。我使用此代码快速检查与新连接数据的连接:
public bool CheckAvailable(string sqlServerName, string login, string password)
{
var testConnectionString = GetConnectionString(sqlServerName, login, password);
if (string.IsNullOrWhiteSpace(testConnectionString))
return false;
var result = false;
try
{
var testContext = new EntityContext(testConnectionString);
result = testContext.Database.Exists();
}
catch (Exception ex)
{
log.Error(exception);
}
return result;
}
private string GetConnectionString(string sqlServerName, string login, string password)
{
var sqlConnectionString = new SqlConnectionStringBuilder
{
DataSource = sqlServerName,
InitialCatalog = ConfigurationProvider.DatabaseName,
UserID = login,
Password = password,
MultipleActiveResultSets = true,
ConnectTimeout = 2 // in seconds
};
var efConnectionString = new EntityConnectionStringBuilder
{
Provider = ProviderName,
Metadata = ConnectionMetadata,
ProviderConnectionString = sqlConnectionString.ToString()
};
return efConnectionString.ConnectionString;
}
SqlConnectionStringBuilder 类型的ConnectTimeout 属性对于快速执行检查闪电非常重要。如果您知道,您的数据库应该可用且应该快速响应,则可以将此值设置为1(在本地安装SQL Server需要100-200毫秒才能检查)。不要设置0,因为它表示没有限制,应该在连接字符串中避免使用。
答案 5 :(得分:0)
我使用了https://www.dartlang.org/install/archive与EntityFramework Core一起使用。
以下是代码:
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;
}
}
}
}
现在你只需要打电话:
if (!context.TestConnection())
{
logger.LogInformation("No database connection. Check the connection string in settings.json. {0}", configuration["connectionString"]);
return;
}