首页 > 解决方案 > 无法打开与 SQL localDB 的连接

问题描述

我正在使用 C# 和 SQL LocalDB 2012 作为数据库引擎构建一个 Windows 窗体应用程序。应用程序第一次启动时,我想创建一个新的数据库服务器实例,创建一个新的登录名并禁用默认的 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();
        }
    }
}

抛出的异常是

建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。(提供者:SQL 网络接口,错误:50 - 发生本地数据库运行时错误。指定的 LocalDB 实例不存在。

EDIT 1,编辑了上面的代码,现在可以复现了 如果你对代码做如下修改,它会毫无例外地运行到最后:第32行,make it

            bool NamedInstanceExists = false;

注释掉第 36 行:

//                testCon.Open();

标签: c#sql-serverdatabase-connectionsql-server-expresslocaldb

解决方案


推荐阅读