Подтвердить что ты не робот

Проверьте, не связана ли Entity Framework с чем-либо

Когда вы создаете новый объект EntityCollection, соединение не пытается открыть базу данных, пока вы не попытаетесь что-то сделать с этой коллекцией. Мне нужно определить, есть ли у коллекции Entity действительное соединение или нет, и я не могу найти эффективный метод ее выполнения.

В настоящее время я получил это в своем коде:

var db = new MyEntityCollection();

try
{
     var checkworking = from c in db.Customers select c;
}
catch 
{ 
     ConnectToBackUp();
}

Это не только ужасный код, но и очень медленный, так как он ждет возраст, чтобы определить, активно ли соединение, прежде чем выбрасывать исключение.

Я знаю, что могу контролировать, как долго он ждет, прежде чем отказаться от использования ConnectionTimeout, но это еще один уродливый хак, который ухудшает ситуацию.

Конечно, лучший способ сделать это?

4b9b3361

Ответ 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, потому что это означает отсутствие ограничений и их следует избегать в строках подключения.