Проверьте, не связана ли Entity Framework с чем-либо
Когда вы создаете новый объект EntityCollection, соединение не пытается открыть базу данных, пока вы не попытаетесь что-то сделать с этой коллекцией. Мне нужно определить, есть ли у коллекции Entity действительное соединение или нет, и я не могу найти эффективный метод ее выполнения.
В настоящее время я получил это в своем коде:
var db = new MyEntityCollection();
try
{
var checkworking = from c in db.Customers select c;
}
catch
{
ConnectToBackUp();
}
Это не только ужасный код, но и очень медленный, так как он ждет возраст, чтобы определить, активно ли соединение, прежде чем выбрасывать исключение.
Я знаю, что могу контролировать, как долго он ждет, прежде чем отказаться от использования ConnectionTimeout, но это еще один уродливый хак, который ухудшает ситуацию.
Конечно, лучший способ сделать это?
Ответы
Ответ 1
Решил это, немного обойдя дома и построив новую строку соединения для тестирования с помощью 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;
}
}
}
Ответ 2
Простейшие:
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;
}
}
}
Ответ 3
Вы просто хотите узнать, действительно ли соединение с БД. Если да, взгляните на objectcontext.databaseExists()
.
Ответ 4
Не следует ли предоставлять такую инфраструктуру на уровне сети или сервера баз данных? Взаимодействие с сервером резервного копирования выглядит странно. Кроме того, это невозможно без ожидания таймаута, потому что сначала вы должны сначала открыть соединение с первичным сервером.
Само соединение доступно на ObjectContext.Connection
. Это свойство должно возвращать экземпляр EntityConnection
, который содержит свойство StoreConnection
, поддерживающее соединение с реальной БД. Вы можете проверить состояние этого соединения.
Ответ 5
В моем приложении пользователь может изменить соединение с базой данных из пользовательского интерфейса. Я использую этот код, чтобы быстро проверить соединение с новыми данными подключения:
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;
}
Свойство ConnectTimeout для типа SqlConnectionStringBuilder очень важно для быстрого обновления проверки. Если вы знаете, что ваша база данных должна быть доступна и должна быстро реагировать, вы можете установить это значение в 1 (при локальном SQL-сервере на проверку требуется 100-200 миллисекунд). Не устанавливайте 0, потому что это означает отсутствие ограничений и их следует избегать в строках подключения.