实体框架代码首先忽略连接字符串,而不是使用IIS

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实体框架代码首先忽略连接字符串,而不是使用IIS相关的知识,希望对你有一定的参考价值。

我有一个使用Entity Framework Code First创建的Web应用程序。在设置它时,我设法将我的数据库连接字符串与我的DBContext匹配,方法是将DBContext的完整命名空间和类指定为连接字符串的名称。

<add name="MyClassProject.EfDbContext"  connectionString="Data Source=.SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=true;User Id=MyUsername;Password=MyPassword;" providerName="System.Data.SqlClient"/>

最初,当我设置项目时,我只是在c: inetpub wwwroot中创建它,然后通过Visual Studio运行它。一切都很好。

现在我正在尝试将代码构建到一个单独的网站文件夹,并让网站在IIS中运行它自己的网站和应用程序池。我已经设置了网站和我的主机文件,但是当我去运行它时,我收到了以下错误。

无法打开登录请求的数据库“MyDatabase”。登录失败。

用户'IIS APPPOOL MyAppPool'登录失败。

我想知道为什么会这样,因为我似乎在我的连接字符串中指定用于数据库的安全用户名和密码....所以为什么它尝试连接我的网站运行的应用程序池?

另外,如何解决这个问题,而不必将SQL Server中的MyAppPool(或网络服务,如果我将其更改为)数据库权限?

更新:我应该提到我使用以下命令初始化我的DBContext类:

namespace MyClassProject 
{ 
    public class EfDbContext : DbContext 
    { 
        public EfDbContext() : base ("MyDatabase") 
        {
        }
    }
}
答案

删除Integrated Security=true;。这是将当前用户关闭的设置。

另一答案

我发现了这个问题。当我使用: base("MyDatabase")初始化我的DBContext类时,它会覆盖web.config中指定的连接字符串。

从我的DBContext类中删除它,数据库已经存在,该站点现在可以在IIS中运行。但是,如果我没有创建数据库,(或者如果我的数据库初始化程序使用DropCreateDatabaseWhenModelChangesDropCreateDatabaseAlways以便它需要重新创建数据库),则初始化程序将失败,因为它将尝试使用没有创建数据库权限的SQL用户。

我的方法是使用: base("MyDatabase")并最初从Visual Studio运行,以便创建数据库。然后将其从代码中删除,将指定的用户添加到SQL Server中的数据库安全性,然后它将允许我的站点在IIS中运行。

另一答案

使用集成安全性时,将从当前正在运行该进程的用户为DB提供令牌。您很有可能从您的用户帐户运行Visual Studio,该帐户可能对您的SQL Server实例具有管理员权限。

当IIS运行您的应用程序时,它使用称为应用程序池(或应用程序池)的东西。您可以在一个池中同时管理多个应用程序。应用程序池还在为池命名的特殊用户帐户下运行。应用程序池用户存在于名为“IIS AppPool”的容器下,因此DefaultAppPool的本地用户是IIS AppPoolDefaultAppPool。如果要授予对本地系统上的资源的访问权限(包括文件权限),您还可以将其授予应用程序池用户或本地组IIS_IUSRS以将其授予所有应用程序池。

请记住,这些是本地帐户,因此它们不会跨越网络边界。要在其他服务器上授予权限,您需要使用域用户(或者更好的域管理服务帐户),或者您可以将应用程序池用户设置为NETWORK SERVICE,然后您可以授予MyDomainMyWebServer$权限(美元符号很重要)。

另一答案

您可以使用Web.config Transform使本地连接搅拌与远程不同(例如在发布模式下)。要开始使用它,您需要使用Visual Studio中的One-Click Publish发布Web应用程序。这是发布网络应用程序的非常方便的方式!

看起来这就是你要找的东西。


或者根据条件设置连接字符串名称:

public EfDbContext() : base (GetConnectionStringName())
{
}

private static GetConnectionStringName()
{
    return RunLocally() : "LocalDatabase" : "RemoteDatabase";
}

private static bool RunLocally()
{
   // implement some how
}

以上是关于实体框架代码首先忽略连接字符串,而不是使用IIS的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码的动态连接字符串首先在运行时 EF6(mssql、mysql、oracle)中用于多个数据库提供程序

为啥 SQL Express 上的实体框架会忽略超时?

实体框架代码首先迁移两个不同的数据库

实体框架代码首先尝试打开错误的数据库

使用实体框架代码首先获得来自同一个父表的两个外键,而无需指定父实体上的集合

在实体框架(脚手架)中使用数据库优先方法时,是不是忽略 HasKey.HasName("PK_123ABC")?