c# - 无法打开与 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();
解决方案
推荐阅读
- vba - 在上标单词前插入 ^{
- ansible - 如何插入一个新行,然后在 Ansible 中附加到它?
- pine-script - 在时间范围内绘制框/矩形
- android - 使用 M1 Mac 构建 APK 时 Flutter 视频无法播放
- api - 将跟踪号硬编码到 URL 中
- python - 为什么我们像这样在 Django 自定义中间件中使用第一类函数?
- linkedin-api - 检索公司详细信息时“查看者无权访问 ADMIN_ONLY VisibilityReduction”
- python - 在反向代理案例中使用 Nginx 和 uWSGI 运行 Flask 应用程序的正确方法是什么?
- reactjs - 连接到 PayPal 的 React 订阅计划
- reactjs - 无法在反应应用程序上使用 axios 从 heroku 获取节点 api