Не удается открыть соединение с SQL localDB - PullRequest
0 голосов
/ 10 июля 2020

Я создаю приложение формы Windows, используя C# и SQL LocalDB 2012 в качестве движка базы данных. При первом запуске приложения я хочу создать новый экземпляр сервера базы данных, создать новый логин и отключить логин по умолчанию Windows, чтобы запретить пользователям доступ к базе данных строк. Сначала я пробую Connection.Open (), чтобы проверить, работают ли экземпляр и новый логин. Если я получаю исключение, я вызываю две процедуры для создания нового экземпляра и входа в систему.

У меня странная ситуация. После создания нового экземпляра, создания нового имени входа и отключения входа по умолчанию Windows SqlConnection.Open () выдает исключение. Странно то, что если я сделаю одно из двух, соединение открывается нормально без исключения:

1 - Если я запускаю код в режиме отладки шаг за шагом, он будет работать без исключения. Если я обычно запускаю тот же код, нажимая кнопку «Пуск», он генерирует исключение.

2- Если я закомментирую исходный код, в котором я пытаюсь выполнить Connection.Open (), чтобы увидеть, есть ли экземпляр и логин уже был создан - если я закомментирую этот Conneciton.Open () и заставлю код создать новый экземпляр и логин, исключение не будет создано.

Вот мой код. Я удалил ненужные части.

// The below throws an exception
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows;

    class Program
    {

    const string connectionString = @"Data Source=(localdb)\MyInstance;User Id=NewLogin;Password=test123;";
    const string TestConnectionString = @"Data Source=(localdb)\MyInstance;Integrated Security=true;";
    const string DBInstanceName = "MyInstance";
    // To replicate, replace 'Ahmad-PC\Ahmad' with your Windows login
    const string changeDBUserSQL =
    @" IF  EXISTS(SELECT * FROM sys.server_principals WHERE name = N'NewLogin')" +
    @" DROP LOGIN[NewLogin]" +
    @" CREATE LOGIN NewLogin" +
    @" WITH PASSWORD = 'test123';" +
    @" CREATE USER NewUser FOR LOGIN NewLogin;  " +
    @" EXEC master..sp_addsrvrolemember @loginame = N'NewLogin', @rolename = N'sysadmin' " +
    @" IF  EXISTS(SELECT * FROM sys.server_principals WHERE name = N'Ahmad-PC\Ahmad')" +
    @" EXEC master..sp_dropsrvrolemember @loginame = N'Ahmad-PC\Ahmad', @rolename = N'sysadmin' ";


    static void Main(string[] args)
        {
            startup();
        }
        static void startup()
        {
            
            SqlConnection testCon = new SqlConnection();
            bool NamedInstanceExists = false;
            try
            {
                testCon.ConnectionString = connectionString;
                testCon.Open();
            }
            catch (Exception ex)
            {
                NamedInstanceExists = false;
            }
            finally
            {
                if (testCon.State == ConnectionState.Open) testCon.Close();
                testCon.Dispose();
            }

            if (!NamedInstanceExists)
            {
                CreateNamedDBInstance();
                CreateNewDBUser();
            }

            SqlConnection conn2;
            conn2 = new SqlConnection();
            conn2.ConnectionString = connectionString;
            try
            {
                // An exception is thrown here
                conn2.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    public static void CreateNamedDBInstance()
    {
        System.Diagnostics.Process process = new System.Diagnostics.Process();
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.FileName = "sqllocaldb.exe";
        startInfo.Arguments = "create " + DBInstanceName;
        process.StartInfo = startInfo;
        try
        {
            process.Start();
        }
        catch (Exception ex)
        {
        }
        while (!process.HasExited) ;
    }

    public static void CreateNewDBUser()
    {
        SqlConnection myConn = new SqlConnection(TestConnectionString);
        SqlCommand myCommand = new SqlCommand(changeDBUserSQL, myConn);
        try
        {
            myConn.Open();
            myCommand.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            if (myConn.State == ConnectionState.Open) myConn.Close();
            myCommand.Dispose();
            myConn.Dispose();
        }
    }
}

Вызванное исключение:

Ошибка, связанная с сетью или спецификацией экземпляра c, при установке соединения с SQL сервером . Сервер не найден или не был доступен. Убедитесь, что имя экземпляра правильное и что сервер SQL настроен на разрешение удаленных подключений. (поставщик: SQL Сетевые интерфейсы, ошибка: 50 - Произошла ошибка времени выполнения локальной базы данных. Указанный экземпляр LocalDB не существует.

ИЗМЕНИТЬ 1, отредактировал приведенный выше код, теперь это воспроизводимый Если вы внесете следующие изменения в код, он будет работать до конца без исключений: Строка 32, сделайте это

            bool NamedInstanceExists = false;

Закомментируйте строку 36:

//                testCon.Open();
...