Entity framework 4 将自定义连接字符串注入实体框架';DBS上下文

Entity framework 4 将自定义连接字符串注入实体框架';DBS上下文,entity-framework-4,connection-string,Entity Framework 4,Connection String,我想将自定义连接字符串插入EF上下文,而不是使用web.config中的连接字符串。其想法是将MVC项目中所有与数据库相关的逻辑移到一个单独的层中。我还希望该层负责正确的连接字符串,而不是我的web应用程序 当前使用上下文的服务正在调用默认构造函数: using (var context = new MyDbContext()) { //... } public <#=Code.Escape(container)#>() : base("name=<#=con

我想将自定义连接字符串插入EF上下文,而不是使用web.config中的连接字符串。其想法是将MVC项目中所有与数据库相关的逻辑移到一个单独的层中。我还希望该层负责正确的连接字符串,而不是我的web应用程序

当前使用上下文的服务正在调用默认构造函数:

using (var context = new MyDbContext()) {
    //...
}
public <#=Code.Escape(container)#>()
    : base("name=<#=container.Name#>")
{
<#
    WriteLazyLoadingEnabled(container);
#>
}
默认构造函数使用
web.config
中的连接字符串名称在内部调用
DbContext

public partial class MyDbContext : DbContext
{
    public MyDbContext()
        : base("name=MyDbContext")
    {
    }

    //...
}
为了注入自定义连接字符串,我需要一个重载构造函数,它将连接字符串作为参数。不幸的是,没有提供这样的构造函数

显然,在
MyDbContext
类中手动添加构造函数重载是一个非常糟糕的主意,因为这个类是自动生成的,很快就会被覆盖。我们别再谈这个了,这是禁止的。句号

由于
MyDbContext
是一个分部类,因此可以在单独的类文件
分部类MyDbContext
中添加额外的构造函数,但这似乎也很难闻。我不知道为什么,但我的大脑说的是个坏主意

经过一些调查,我发现,可以通过编辑T4模板
Model.Context.tt
,告诉EF包含这个额外的构造函数,它是C#和一些模板标记的混合体。以下是原始构造函数:

using (var context = new MyDbContext()) {
    //...
}
public <#=Code.Escape(container)#>()
    : base("name=<#=container.Name#>")
{
<#
    WriteLazyLoadingEnabled(container);
#>
}
public()
:base(“name=”)
{
}
添加类似逻辑以生成包含连接字符串的重载构造函数显然很容易:

public <#=Code.Escape(container)#>(string nameOrConnectionString)
    : base(nameOrConnectionString)
{
<#
    WriteLazyLoadingEnabled(container);
#>
}
public(字符串名称或连接字符串)
:base(名称或连接字符串)
{
}
我尝试了这一点,并注意到,重新生成模型类和从DB更新模型都不会影响T4模板,因此额外的构造函数将始终存在。好!!乍一看,这似乎是一个合适的解决方案,但

我的问题是:这真的是一个好的解决方案吗?

让我们再次比较这三个选项:

  • 编辑自动生成的类(好的,我们同意忘记这个)
  • 在分部类文件中添加构造函数
  • 编辑T4模板,告知EF生成附加构造函数
  • 在我看来,从这三个选项中,第三个似乎是最方便、最干净的解决方案。你的意见是什么?有人有好的理由,为什么这是个坏主意?是否有更多的选项可以插入连接字符串,可以使用自定义的
    connectionFactory
    ?如果是这样的话,我该怎么做呢?

    就像,我用部分类替换了我的T4模板方法。事实证明,这确实比我目前知道的任何其他解决方案都简单和直观

    自动生成的类如下所示:

    public partial class MyDbContext : DbContext
    {
        public MyDbContext() : base("name=MyDbContext")
        {
        }
    
        //...
    }
    
    我刚刚添加了另一个同名的分部类。问题解决了

    public partial class MyDbContext 
    {
        public MyDbContext(string nameOrConnectionString)
                 : base(nameOrConnectionString) 
        {
        }
    }
    

    从你提供的3个选项中,我宁愿选择选项2。难道没有引入partial关键字来解决自动生成文件的问题吗?在我看来,使用T4模板带来了额外的复杂性,维护开发人员需要了解的不仅仅是一件事(并不是每个人都熟悉T4),但是扩展部分类是更标准的c#开发

    然而,我不知道“是否有一个真正好的解决方案”的答案。引入工厂会带来新的代码来维护、测试和理解,我不确定这个抽象在这里是否有帮助,因为工厂本身需要用适当的构造函数实例化dbcontext(您无论如何都必须提供构造函数)

    编辑:


    再次考虑一下:工厂可能有助于从另一个位置解析连接字符串(您说过不希望在web.config中使用connectionstring),但这仍然不能解决构造函数问题

    事实上,我已经使用了一个连接字符串工厂,它成功地从我的UI项目中删除了任何与数据访问相关的逻辑,并将其移到了它所属的位置,即数据访问项目。正如您所提到的,它没有解决构造函数问题。