Я создаю приложение формы 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();