【问题标题】:Inject custom connection string into Entity Framework's DbContext将自定义连接字符串注入实体框架的 DbContext
【发布时间】:2013-04-02 14:18:53
【问题描述】:

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

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

using (var context = new MyDbContext()) {
    //...
}

默认构造函数在内部调用DbContext,使用来自web.config的连接字符串的名称:

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

    //...
}

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

很明显,在MyDbContext 类中手动添加构造函数重载是一个非常糟糕的想法,因为这个类是自动生成的,并且很快就会被覆盖。我们不要再谈论这个了,这是被禁止的。期间。

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

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

public <#=Code.Escape(container)#>()
    : base("name=<#=container.Name#>")
{
<#
    WriteLazyLoadingEnabled(container);
#>
}

显然很容易添加类似的逻辑来生成包含连接字符串的重载构造函数:

public <#=Code.Escape(container)#>(string nameOrConnectionString)
    : base(nameOrConnectionString)
{
<#
    WriteLazyLoadingEnabled(container);
#>
}

我试过这个并注意到,重新生成模型类和从 DB 更新模型都不会影响 T4 模板,因此额外的构造函数将始终在那里。好的!乍一看,这似乎是一个合适的解决方案,但是......

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

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

  1. 编辑自动生成的类(好的,我们同意忘记这个)
  2. 在部分类文件中添加构造函数
  3. 编辑 T4 模板以告诉 EF 生成额外的构造函数

从这三个选项中,第三个在我看来是最方便和最干净的解决方案。你有什么意见?有人有充分的理由,为什么这是一个坏主意?是否有更多选项可以注入连接字符串,可能使用自定义connectionFactory?如果是这样,我该怎么做?

【问题讨论】:

    标签: entity-framework-4 connection-string


    【解决方案1】:

    @shaft proposed 一样,我将 T4 模板方法替换为使用部分类。事实证明,这确实比我目前知道的任何其他解决方案都简单直观。

    自动生成的类如下所示:

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

    我刚刚添加了另一个同名的部分类。问题已解决。

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

    【讨论】:

      【解决方案2】:

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

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

      编辑:

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

      【讨论】:

      • 我实际上已经在使用连接字符串工厂,它成功地从我的 UI 项目中删除了任何与数据访问相关的逻辑,并将其移动到它所属的位置,即数据访问项目。正如你提到的,它没有解决构造函数问题。
      猜你喜欢
      • 1970-01-01
      • 2014-02-03
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      相关资源
      最近更新 更多