如何通过Entity Framework避免对空/ null数据库进行连接

6

我们使用实体框架来读取现有数据库。以下是我们代码的简化版本。

using (my context context = new mycontext())
{
    if(context.Database.Connection.State == System.Data.ConnectionState.Closed)
    {
        _logger.Info(" Opening the connection to the database");
        context.Database.Connection.Open();
    }

    context.Configuration.LazyLoadingEnabled = false;          
    IQueryable<mymodel> people;
    people = context.People.OrderBy(x => x.Firstname);
    _lstContacts = people.ToList();

    if (context.Database.Connection.State != System.Data.ConnectionState.Closed)
    {
        context.Database.Connection.Close();
        context.Database.Connection.Dispose();
        _logger.Info(" Connection to the database Closed");
    }
}

它的工作效果一直都是百分之百,但是...... 在我们的UAT环境中,我们可以看到连接到Microsoft SQL服务器的失败连接,并显示以下错误信息:
“登录失败,用户为“my user”。原因:无法打开明确指定的数据库“null”。客户机我的IP。”
对我们来说,这些是幽灵连接,因为当我们在SQL服务器中看到错误时,我们的代码并没有被执行。 最初,我们没有显式地关闭和打开连接,只是添加了它,试图控制EF何时打开和关闭连接,但这并没有解决问题。
我们的连接字符串采用以下格式:
<add name="MYCN" connectionString="metadata=res://*/CVs.Cvs.csdl|res://*/CVs.Cvs.ssdl|res://*/CVs.Cvs.msl;provider=System.Data.SqlClient;provider connection string="data source=myserver\;initial catalog=mydatabase;Integrated Security=;User ID=myuser;Password=XXXXXXX;MultipleActiveResultSets=True;App=EntityFramework"/>

如您所见,我们在连接字符串中指定了数据库,而我们的用户只能访问我们的数据库,因此当EF在连接字符串中不包含该数据库时,我们能理解错误原因,但我们并不明白为什么它尝试执行这些连接。

我们知道这些连接来自我们的应用程序,因为我们是唯一使用该特定用户的人,IP是我们服务器的IP,而且因为SQL Server日志告诉我们应用程序是“EntityFramewrok”


那个错误的状态号是多少?它应该告诉类似这样的东西,例如这里的状态号是1::> Msg 18456,Level 14,State 1,Server <server name>,Line 1 等等等等... - Eray Balkanli
你好,我们没有状态号码,实际上,我们没有从应用程序端收到任何错误,错误在服务器端;似乎我们的代码没有执行,但是一切都指向我们的应用程序,因为IP是我们服务器的IP,用户仅在我们的connectionstring.config中配置,应用程序名称是entityframewrork。我会与DBA核实,以确定他们是否能够获取实际错误。 - Vicent Galiana
你尝试过这个解决方案了吗? - Steve
我看到你在XML(可能是web.config)中声明了你的连接字符串。你的DbContext初始化代码是什么样的?你的应用程序中第一个引用dbContext的地方在哪里(owin?)? - DiscipleMichael
我们完全依赖于Entity Framework。我们与数据库交互的第一次尝试是使用新上下文,这是我示例代码的第一行:using (mycontext context = new mycontext()) - Vicent Galiana
你能展示一下你的DB上下文构造函数吗? - DiscipleMichael
2个回答

3

我个人没有见过这个错误,但为您进行了研究,并发现许多人都遭受了同样的问题,可以在此讨论中找到解决方法: https://blogs.msdn.microsoft.com/sql_protocols/2006/02/21/understanding-login-failed-error-18456-error-messages-in-sql-server-2005/

我阅读了指定网站中的所有消息,以下是提供的解决方案,至少有一个其他用户证实它有效。由于您没有在问题中指定版本,您可能不使用2005,但我认为某些解决方案仍然适用于您,请尝试以下列表。

解决方案列表:

1) 请检查此错误的状态号码,并按状态号码搜索解决方案,可能会给您更准确的解决方案建议。最常见的状态已列出: List item

您可以在此处找到所有状态错误描述: https://sqlblog.org/2011/01/14/troubleshooting-error-18456

2) 确保用户名和密码正确。

3)

  • 使用 Windows 身份验证登录到 SQL Server。
  • 右键单击出现的查询窗口, 并选择 "在对象资源管理器中打开服务器"
  • 转到对象浏览器,打开 "安全性" 文件夹,然后是 "登录" 文件夹。
  • 双击用户“sa”并更改密码。 此外,请像上面提到的另一个用户一样,取消选中“强制密码策略”,以重置密码。

4) 尝试更改密码并关闭策略,并尝试使用新密码。

exec sp_password @new = ‘sqlpassword’, @loginame = ‘sa’
alter login sa
with password = ‘sqlpassword’ unlock,
check_policy = off,
check_expiration = off

5) 以管理员身份运行您的应用程序/浏览器和SSMS(如果您在使用它)。

6)

  • 打开Windows服务
  • 配置 Microsoft Single Sign-on 服务使用正确的帐户
  • 打开中央管理 >> 操作 >> 管理单一登录设置
  • 配置属性以使用与 Microsoft 'Single Sign-on Service 相同的帐户

7) 转到 Sql server 配置管理器并启用 TCP/IP 和命名管道

8)

  • 转到 sql server
  • 右键单击服务器,选择属性
  • 点击安全性
  • 在服务器身份验证上,启用 SQL Server 身份验证

以下可能会有所帮助:

https://www.wikitechy.com/errors-and-fixes/sql/login-failed-error-18456-severity-14-state-38-reason-failed-to-open-the-explicitly-specified-database

https://dba.stackexchange.com/questions/90445/login-failed-for-user-error-18456-severity-14-state-38


嗨,当我们执行代码时,我们的应用程序可以正常运行。如果我们通过SQL管理器使用相同的凭据,在显式配置时可以连接到数据库,如果不这样做,我们会得到相同的错误。我们的问题是,我们不知道为什么我们应用程序域内的某些东西正在打开这些连接,而不使用数据库。 - Vicent Galiana
@VicentGaliana 你的代码中是否使用了 "using" 结构?应该像这样写: using(SqlConnection conn = new SqlConnection("connection info")) { // 你的代码 } - Eray Balkanli

0

我认为这只是我的用户在UAT环境中的访问问题。只需确保我的用户在UAT数据库的UAT环境中具有访问权限,您就应该没问题了。


如果我们有一个永久性错误,那么这是有道理的,但是我们的功能在应该工作时是正常的,问题只出现在这些“幽灵连接”上,我们不知道是什么/为什么打开。 - Vicent Galiana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接