【问题标题】:Entity Framework Code First ignoring connection string, using IIS insteadEntity Framework Code First 忽略连接字符串,改用 IIS
【发布时间】:2013-03-04 22:28:16
【问题描述】:

我有一个使用 Entity Framework Code First 创建的 Web 应用程序。在设置它时,我通过将 DBContext 的完整命名空间和类指定为连接字符串的名称,设法将我的 DB 连接字符串与我的 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(或网络服务,如果我将其更改为那个)DB 权限?

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

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

【问题讨论】:

    标签: entity-framework entity-framework-4 ef-code-first connection-string dbcontext


    【解决方案1】:

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

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

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

    【讨论】:

    • base("MyDatabase") 表示来自 Web.config 的连接字符串名称。所以你只需要为不同的部署点设置不同的连接字符串。或者根据条件设置不同的名称。
    【解决方案2】:

    删除Integrated Security=true;。这是让当前用户离开的设置。

    【讨论】:

    • 我已经从连接字符串中删除了该属性,但仍然遇到同样的问题。我什至尝试过明确设置 Integrated Security=false;但这也没有用。
    • @SeanHolmesby 你确定它使用那个连接字符串吗?
    • 当我通过 Visual Studio 运行时(当它工作时),它肯定会将数据添加到我试图引用的数据库中。我有:- namespace MyClassProject { public class EfDbContext : DbContext { public EfDbContext() : base ("MyDatabase") { } } } ......然后......
    • 我的种子数据正在使用 CreateDatabaseIfNotExists... 但是当我运行 Visual Studio 时数据库已经存在。然后我进去,将用户添加到数据库的安全性中,并尝试通过 IIS 运行。
    【解决方案3】:

    使用集成安全性时,数据库会从当前运行进程的用户那里获得一个令牌。您很可能从您的用户帐户运行 Visual Studio,该帐户可能对您的 SQL Server 实例具有管理员权限。

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

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

    【讨论】:

      【解决方案4】:

      您可以使用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
      }
      

      【讨论】:

        猜你喜欢
        • 2011-10-24
        • 2011-05-06
        • 1970-01-01
        • 2023-04-09
        • 2012-05-10
        • 2011-09-19
        • 2012-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多