【问题标题】:How to open a connection to a SQL Server database that is already in use in c#?如何打开与 C# 中已在使用的 SQL Server 数据库的连接?
【发布时间】:2013-02-26 16:12:53
【问题描述】:

我在 asp.net mvc 3 项目中连接到数据库。此外,我的解决方案中有一个 Windows 服务项目,它在某些事件中将数据写入该数据库。

困难在于当windows服务项目的代码需要连接数据库时我得到SqlException

无法打开登录请求的数据库“WebStore”。登录失败。用户“NT AUTHORITY\SYSTEM”登录失败。

这里是windows服务的代码:

    public static string GetConnectionString()
    {
        return @"Data Source=(LocalDB)\v11.0; DataBase=WebStore; 
                AttachDbFilename=myDbFullPath;
                Integrated Security=True;Connect Timeout=30";
    }

在写入数据库的事件处理程序中:

using (var conn = new SqlConnection(GetConnectionString()))
{
    conn.Open();
    var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
    const string cmd1 = "UPDATE Products SET ImageModifiedDate=@date WHERE ProductId=@productId";

    using (var command = new SqlCommand(cmd1, conn))
    {
        command.Parameters.AddWithValue("@productId", productId);
        command.Parameters.AddWithValue("@date", DateTime.Now);
        command.ExecuteNonQuery();
    }
 }

异常发生在conn.Open(); 行。如果我评论这一行,command.ExecuteNonQuery(); 将出现新异常:

InvalidOperationException:ExecuteNonQuery 需要打开且可用的连接。连接已关闭。

问题:如何打开与已附加在另一个项目中的 SQL Server 数据库的连接?

编辑 1: 我使用以下代码在我的数据库中创建新登录名和新用户:

CREATE LOGIN user1
WITH PASSWORD = 'password1';
GO
CREATE USER user1 FOR LOGIN user1;
GO

我试图在服务器资源管理器中附加我的数据库:我选择“使用 Sql Server 身份验证”并输入用户名:user1,密码:password1。

我得到:

尝试附加到数据库失败,并显示以下信息:
用户“user1”登录失败。

编辑2:我设置了这个属性:

processInstaller.Username = "user1";
processInstaller.Password = "password1";

然后在 cmd 中运行:

installutil /name=user1 /password=password1 MyService.exe

我得到 System.ComponentModel.Win32.Exception:
the comparison between user names and security identifiers haven't been executed.

我做错了什么?

编辑 3: 我在 services.msc 和 processInstaller“帐户”属性中设置了我的用户名和密码,我用“本地系统”离开了。它会运行,但是当我更改图像(以及尝试访问我的数据库的事件处理程序)时,我得到:

Cannot attach file 'C:\Users\Aleksey\repos\working-copy\WebStore\WebStore\App_Data\WebStore.mdf' as database 'WebStore' because this file is already in use for database 'C:\USERS\ALEKSEY\REPOS\WORKING-COPY\WEBSTORE\WEBSTORE\APP_DATA\WEBSTORE.MDF',

在连接字符串中,我添加了在数据库中创建的用户凭据:

User Id=user1;PASSWORD=password1;

此外,当我尝试在服务器资源管理器中添加连接并使用 Sql Server Authentication 并输入 user1password1 时,我会收到来自 Edit 1 的消息强>。

我应该在服务器资源管理器*Windows Authentication* 和 Windows 服务中的连接字符串中使用:User Id=user1;PASSWORD=password1; 吗?

【问题讨论】:

  • 在自己的凭证/身份下调试代码时是否还会出现登录异常?另外,我很少在字符串上使用@指令,这会改变'\'的行为,使得'\v'是正确的还是应该是'\\v'? (再说一次,我很少用@,也不知道。)
  • 在数据库中创建新的登录名并在连接字符串中传递用户名和密码。
  • 你试过用网络服务账号打开吗?该帐户应绕过传统登录。因为它就像网络上的计算机一样,所以它不应该有与 SQL 接口的问题。 msdn.microsoft.com/en-us/library/windows/desktop/…
  • 我没试过用网络服务账号打开。将检查链接
  • 系统用户是否有登录你的sql server的权限,是否有访问WebStore DB的权限?您的 Windows 服务正在以该用户身份运行并尝试使用这些凭据进行连接。我认为问题不在于两个同时连接。您还可以通过其属性更改您的服务的运行对象。

标签: c# asp.net sql database-connection sql-server-2012


【解决方案1】:
Cannot open database "WebStore" requested by the login. The login failed. Login failed for user 'NT AUTHORITY\SYSTEM'.

发生这种情况是因为您的服务使用 LocalSystem 帐户运行,并且您使用集成安全性连接到 SQL 服务器,而 SYSTEM 不应该在那里访问。所以三选一:

  1. 切换到 SQL Server 身份验证。这包括在数据库中创建登录名并修改连接字符串
  2. 使用具有它真正需要的唯一权限的特定用户运行服务(这实际上是一个好主意),并授予该用户对数据库的访问权限,以便它可以通过集成安全性进行连接。这是最简单的,因为它不需要对代码进行任何更改
  3. 如果您确实需要以 SYSTEM 身份运行,则可以使用模拟通过 LogonUser 切换到另一个用户(如选项 2 中的用户)。这样一来,您最终只能使用选项 2 来访问数据库,并为其余的服务代码保留 SYSTEM 权限。

第二个错误

InvalidOperationException: Opened and available connection is needed for ExecuteNonQuery. Connection is closed.

是第一个错误引起的,打开连接失败导致这个。如果没有打开的连接,您将无法执行任何操作,ADO.Net 可以确保这一点。

所以第一个错误是唯一重要的错误。

我建议您使用选项 2,因为这是安全实践方面的最佳选择,并且由于您在集成安全中运行,因此您不必存储任何密码,如果您的应用程序有多个具有不同数据库、用户、密码以及您拥有什么的环境。每个环境、权限和您设置的只是一个用户。

【讨论】:

  • 究竟如何实现第二种方法?请检查我上面的编辑。谢谢!
  • 安装时不要设置用户,运行 services.msc 并在那里编辑服务属性
  • 你能一步一步描述这个过程吗,因为我不完全明白该怎么做。提前致谢!
  • 以管理用户身份运行 services.msc。找到您的服务,双击,转到登录选项卡,从本地系统更改为“此帐户”,放置一个可以访问具有集成安全性的 sql server 的用户
猜你喜欢
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多