如何避免实体框架与空/空数据库的连接

Posted

技术标签:

【中文标题】如何避免实体框架与空/空数据库的连接【英文标题】:How to avoid connections against empty/null database by Entity Framework 【发布时间】:2019-12-01 05:32:07 【问题描述】:

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

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");
    

它 100% 的时间都有效,但是... 在我们的 UAT 环境中,我们可以看到与 Microsoft SQL 服务器的连接失败并出现以下错误:

用户“我的用户”登录失败。原因:无法显式打开 指定的数据库“空”。客户端我的 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 服务器中的日志告诉我们应用程序是“EntityFramewrok”

【问题讨论】:

该错误的状态编号是多少?它应该告诉类似的内容,例如这里的状态编号为 1 ::> Msg 18456, Level 14, State 1, Server , Line 1 etc etc... HI,我们没有状态号,实际上我们没有从应用程序端得到任何错误,错误在服务器 sid;似乎我们的代码没有被执行,但是,一切都指向我们的应用程序,因为 IP 是我们服务器的 IP,用户只在我们的 connectionstring.config 中配置,应用程序名称是 entityframewrork。我将与 DBA 核实,以防他们得到实际错误。 你试过这个solution吗? 我看到您在 xml 中声明了连接字符串(可能是 web.config)。您的 dbcontext 初始化代码是什么样的?应用程序中引用 dbContext(owin?)的第一个点在哪里? 我们完全依赖实体框架。我们与数据库交互的第一次尝试是使用新上下文,即我示例的第一行代码: using (mycontext context = new mycontext()) 【参考方案1】:

我之前没有亲自看到错误,但是为您研究并看到很多人遇到了这里讨论的相同问题:https://blogs.msdn.microsoft.com/sql_protocols/2006/02/21/understanding-login-failed-error-18456-error-messages-in-sql-server-2005/

我阅读了指定网站中的所有消息,以下是提供的解决方案,并且至少有其他用户确认它有效。您可能不会使用 2005,因为您没有在问题中指定您的版本,我相信一些解决方案仍然适用于您。试试下面的列表。

解决方案列表:

1) 请检查此错误的状态编号,并在消息之外通过状态编号搜索解决方案,可能会给您更准确的解决方案建议。列出了最常见的状态:

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

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

3)

使用 Windows 身份验证登录到 SQL Server。 在出现的查询窗口中单击鼠标右键,选择“在对象资源管理器中打开服务器” 转到对象资源管理器并打开“Security”文件夹,然后打开“Logins”文件夹。 双击“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 Service 以使用正确的帐户 打开管理中心 >> 操作 >> 管理单点登录设置 配置属性以使用与 Microsoft 单一登录服务相同的帐户

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 管理器使用相同的凭据,我们可以在显式配置数据库时连接到数据库,否则会出现相同的错误。我们的问题是我们不知道,我们的应用程序域中的某些东西是如何在不使用数据库的情况下打开这些连接的。 @VicentGaliana 您是否在代码中使用“使用”结构?应该是这样的: using(SqlConnection conn = new SqlConnection("connection info")) // 你的代码 【参考方案2】:

我认为这只是 UAT 环境中 myuser 的访问问题。只需确保 myuser 在 UAT 环境中可以访问 UAT 数据库,您就可以了。

【讨论】:

如果我们有一个永久错误是有道理的,但是我们的功能在它应该工作的时候工作,问题只是这些“幽灵连接”我们不知道什么/为什么打开.

以上是关于如何避免实体框架与空/空数据库的连接的主要内容,如果未能解决你的问题,请参考以下文章

将 bigquery 中的数组与空数组连接起来

我应该如何编辑实体框架连接字符串?

我如何避免为实体框架添加哈希到我的实体名称

使用“不存在”与空关系测试混淆

PostgreSQL unnest 与空数组

如何在实体框架和函数中处理空值