使用连接字符串和 dapper 时如何在运行时更改初始目录

How to change initial catalog at runtime when using a connection string and dapper

我正在编写 MVC C# 应用程序。我使用 dapper 作为轻量级 ORM。我的连接字符串是用服务器和初始目录定义的,目前如果我需要访问不同的数据库,我会定义另一个连接字符串,并使用 Ninject 绑定来根据我正在注入的管理器使用特定的连接字符串像这样:

public class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IDbConnection>().To<SqlConnection>()
           .WhenInjectedInto<DashboardManager>()
           .InRequestScope()
           .Named("myDashboard")
           .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbDashboard"].ConnectionString);

        Bind<IDbConnection>().To<SqlConnection>()
           .WhenInjectedInto<ScoreboardManager>()
           .InRequestScope()
           .Named("myScoreboard")
           .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbScoreboard"].ConnectionString);

    }
}

不幸的是,如果我在同一个管理器中有代码需要调用与最初指定的目录不同的数据库上的存储过程,这将不起作用。

问题是:我可以只定义一个连接字符串,丢掉上面的所有 ninject 绑定内容,然后简单地将 Initial Catalog 即时更改为指向不同数据库的点吗?

您的绑定是否需要 NamedWhenInjectedInto 约束?

我相信你有一个 class 需要两个 connectionstrings,这可以使用 Named 绑定来实现:

Bind<IDbConnection>().To<SqlConnection>()
   .InRequestScope()
   .Named("myDashboard")
   .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbDashboard"].ConnectionString);

Bind<IDbConnection>().To<SqlConnection>()
   .InRequestScope()
   .Named("myScoreboard")
   .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbScoreboard"].ConnectionString);

而您的 class 可以获得两个连接:

public class ClassWith2DbDependency // <-- I would question this class for SRP violation
{
    private readonly IDbConnection _dashboardConnection;
    private readonly IDbConnection _scoreboardConnection;

    public ClassWith2DBDependency(
        [Named("myDashboard")] IDbConnection dashboardConnection
        [Named("myScoreboard")] IDbConnection scoreboardConnection)
    {
        _dashboardConnection = dashboardConnection;
        _scoreboardConnection = scoreboardConnection;
    }

    public void WriteTo2Dbs()
    {
        // execute dashboard DB procedure
        // execute scoreboard DB procedure
    }
}

Can I just define one connection string, lose all the ninject binding stuff above, and simply change the Initial Catalog to a point to a different database on the fly?

更改 Initial Catalog 不会影响现有的 SqlConnection。可以自己管理依赖关系,但你仍然需要 2 connectionstrings:

public class ClassWith2DbDependency
{
    public void WriteTo2Dbs()
    {
        var dashboardCon = ConfigurationManager.ConnectionStrings["dbDashboard"].ConnectionString;
        using (SqlConnection connection = new SqlConnection(dashboardCon))
        {
            // execute dashboard DB procedure
        }

        var scoreboardCon = ConfigurationManager.ConnectionStrings["dbScoreboard"].ConnectionString;
        using (SqlConnection connection = new SqlConnection(scoreboardCon))
        {
            // execute scoreboard DB procedure
        }
    }
}

但是,我推荐这种方法,上面class违反了DI原则,Opaque Dependencies.


我没看过你的代码,但你好像没有用 Repository Pattern?这可能是一个不错的选择...