在同一解决方案中的不同项目中访问EF连接字符串MVC

4
在尝试实践关注点分离的过程中,我正在将一个ASP.NET MVC项目中的Models和DBContext放入同一解决方案中的一个单独项目中。现在,我有了一个Project.Web项目,其中包含ViewModels、Controllers和Views,还有一个Projects.Entities用于Models和DAL。而具有ConnectionString属性的web.config文件位于Project.Web项目中。
  <connectionStrings>
    <add name="SchoolContext" connectionString="Data Source=localhost;Initial Catalog=ContosoUniversity1;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

主页控制器:

public class HomeController : Controller
{
    private SchoolContext db = new SchoolContext();

Project.Entities

public class SchoolContext : DbContext
{
    public SchoolContext() : base("SchoolContext")
    {

    }

我的问题是,因为SchoolContext的连接字符串名称在另一个项目的web.config文件中,所以DBContext无法获取它。我该如何解决这个问题?当所有MVC组件都在同一个项目中时,一切都正常工作。

使用带有连接字符串参数的DbContext构造函数。然后您可以从Web项目中传递此参数,而您的数据访问层不需要保留重复值。 - Jasen
我认为那就是我试图做的事情,但不太确定在哪里实现。你能给我一个快速的例子吗?这类似于我尝试过但无法正常工作的代码:public partial class MyEFEntities { public MyEFEntities(string connectionstring) : base(connectionstring) { } } - Reza
3个回答

2
这基本上是我设置解决方案的方式。我可以让Web项目的web.config或测试项目的app.config定义连接字符串。
数据项目
public class SchoolContext : DbContext
{
    public SchoolContext(string connectionString)
        : base(connectionString) { }
}

网络项目

web.config

<configuration>
    <connectionStrings>
        <add name="SchoolContextDb" connectionString="Data Source=..." />
    </connectionStrings>
    <appSettings>
        <add key="SchoolContext" value="SchoolContextDb" />
    </appSettings>
    ...
</configuration>

使用
string ConnectionString = System.Configuration.ConfigurationManager.AppSettings["SchoolContext"];

SchoolContext db = new SchoolContext("Name=" + ConnectionString);

我使用依赖注入容器,所以只需要在应用程序启动代码中查找连接字符串一次。但你也可以将 ConnectionString 变量设置为全局变量或在基础控制器中设置。

0

我在初始问题中使用的代码非常好用,即使将DAL分割成不同的项目也能正常运行。问题在于 EF Code First Initializer 没有被执行,这是因为当我将初始化器代码移动到自己的项目中时,在 web.config 文件中没有正确的程序集。修改后的 web.config 应该如下所示(我遗漏了 .Entities,在名为 ContosoUniversity.Entities 的项目中包含 DAL)。

  <entityFramework>
    <contexts>
      <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity.Entities">
        <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity.Entities" />
      </context>
    </contexts>

0

默认情况下,入口点解决方案会检查 web.config 中的 connectionstring,并继续检查引用项目。

  1. 使用此代码片段,它不会获取更多详细信息,您是否遇到任何错误。
  2. 您可以验证更改 dbcontext 名称后是否出现错误。默认情况下,如果未设置,则会使用定义有 dbcontext 类的类名。
  3. 验证...
  4. 我希望您已经在配置文件中设置了设置。请验证上下文和命名空间。

  <entityFramework>
<contexts>
      <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity.DAL">
        <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity.DAL" />
      </context>
 </contexts>
 </entityFramework>


我正在努力理解你的问题,因为它不是很清楚。1)是的,我使用上述代码时收到了错误消息。无法从程序集'ContosoUniversity'中加载类型'ContosoUniversity.DAL.SchoolContext'。2)我将ConnectionString名称更改为其他内容,并获得与1相同的错误。4)是的,已经明确说明配置文件中有一个connectionString。如果我将DAL和Models文件夹放在我的WebUI项目中,一切都可以正常工作。 - Reza
更新了我的回复...似乎与汇编相关的上下文在配置中不匹配。如果这样行不通,你需要提供你的配置文件。 - nikudale
我尝试了你的片段中关于'databaseinitializer'的代码,但仍然存在问题。不过,我只是注释掉了初始化程序,解决方案运行良好并显示数据。所以至少我知道这不是无法获取连接字符串的问题。然而,我很困惑为什么SchoolInitializer类没有执行,它位于Project.Entities项目中的ContosoUniversity.DAL命名空间中。 - Reza
本质上它就是这个例子 http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application,但我把数据访问层(DAL)移动到了自己的项目中。 - Reza
我希望我的回复对你的问题有所帮助,如果是的话,请将其标记为答案。 - nikudale

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