Не удается немедленно подключиться к вновь созданной базе данных SQL Server - PullRequest
8 голосов
/ 15 февраля 2012

Я создаю базу данных, используя Объекты управления SQL Server .

Я написал следующий метод для создания базы данных:

public static void CreateClientDatabase(string serverName, string databaseName)
{
    using (var connection = new SqlConnection(GetClientSqlConnectionString(serverName, String.Empty)))
    {
        var server = new Server(new ServerConnection(connection));
        var clientDatabase = new Database(server, databaseName);

        clientDatabase.Create();
        server.ConnectionContext.Disconnect();
    }
}

Вскоре после этого явызовите другой метод для выполнения сценария SQL для генерации таблиц и т. д .:логин.Ошибка входаНе удалось войти в систему для пользователя 'user'.

Если я попытаюсь пройтись по инструкциям в отладчике, это исключение никогда не произойдет, и скрипт выполнится нормально.

Мое единственное предположение, что серверу требуется некоторое время для инициализации базы данных, прежде чем ее можно будет открыть.Это точно?Есть ли способ определить, готова ли база данных, кроме попыток и неудачных попыток подключения?

Редактировать: Следует отметить, что база данных определенно создается во всех случаях.

Редактировать 2: Перед созданием базы данных я вызываю System.Data.Entity.Database.Exists метод EntityFramework.dll, чтобы проверить, существует ли база данных.Если я удаляю этот вызов, все, кажется, работает как ожидалось.Это похоже на то, что этот вызов кэширует результат и портит последующие соединения от просмотра новой базы данных (независимо от того, используют ли они Entity Framework или нет).

Редактировать 3: Я заменил метод EntityFramework Database.Exists на SMO-подход, используя Server.Databases.Contains(databaseName).Я получаю ту же проблему в том, что база данных не может быть открыта сразу после создания.Опять же, если я не проверю, существует ли база данных до ее создания, я могу сразу же открыть ее после ее создания, но я бы хотел иметь возможность проверить ее существование до ее создания, поэтому я не пытаюсь создать существующую базу данных.

И EntityFramework Database.Exists, и SMO ​​Server.Databases.Contains оба просто выполняют SQL, который ищет имя базы данных в master.sys.databases.Я не понимаю, почему / как это мешает соединениям с базой данных.

Ответы [ 4 ]

8 голосов
/ 17 февраля 2012

База данных, которая только что подключилась, не обязательно готова к принятию соединений.Чтобы определить, когда база данных может принимать соединения, запросите столбец collation_name в sys.databases или свойство Collation в DATABASEPROPERTYEX.База данных может принимать соединения, когда сопоставление базы данных возвращает ненулевое значение.

1 голос
/ 11 января 2017

В моем случае оказалось, что проблема не в том, что вновь созданная база данных не готова.Но проблема заключалась в том, что SqlConnection.Open() явно использовал сбойное кэшированное соединение, которое затем просто снова возвращало ту же ошибку.

Когда я вызываю статический метод SqlConnection.ClearAllPools(), прежде чем пытаться открытьвновь созданная база данных, она отлично работает!

См. также этот вопрос.

1 голос
/ 17 февраля 2012

Имя базы данных "запрошено при входе в систему. Ошибка при входе в систему. Ошибка при входе в систему для пользователя 'пользователь'

Здесь нужно отметить одну вещь - сообщение об ошибке окружает безопасность. Как вы пытаетесь войти в новую базу данных (т. Е. Какой тип защиты используется для строки подключения для нового подключения к базе данных)? Если вы используете аутентификацию SQL, вам нужно будет запустить sp_adduser, чтобы предоставить доступ для входа в базу данных.

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

0 голосов
/ 15 февраля 2012

Вы должны подойти к созданию базы данных немного по-другому. Код ниже правильно обрабатывает создание базы данных. Попробуй это;)

private void CreateDatabase(string databaseName)
{

    Microsoft.SqlServer.Management.Smo.Server sqlServer = 
            new Microsoft.SqlServer.Management.Smo.Server(_connection);

    Database createdDatabase = new Database();
    createdDatabase.Name = databaseName;
    createdDatabase.Parent = sqlServer;
    createdDatabase.Create();

}

В приведенном ниже коде _connection, кстати, является

Microsoft.SqlServer.Management.Smo.ServerConnection
объектом.

[Изменить] Изменен код, чтобы исключение больше не проглатывалось.

...