0

我正在研究 Asp.Net MVC 和 ServiceStack。我正在尝试使用 servicestack ormlite 连接到 sql server 数据库。像

 var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;
 container.Register<IDbConnectionFactory>(
 new OrmLiteConnectionFactory(connectionString,
                    SqlServerOrmLiteDialectProvider.Instance)
                {
                    ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
                });

我能够连接到数据库,但在我的场景中,我需要动态更改连接字符串。这意味着我需要从请求正文中读取内容并准备一个连接字符串。在 servicestack 中,我们在 AppHost 类中配置 sql server 连接字符串,这意味着在应用程序启动时。但我需要在我的控制器中设置连接字符串。我已经尝试将它放在会话中并在 ClassLibrary ServiceBase 类中使用该会话。但我无法在类库中使用 asp.Net 会话。如何在服务堆栈中动态更改 sql server 连接字符串。所以请指导我。

4

1 回答 1

3

我会更改在IDbConnectionFactory请求范围内重用,而不是当前默认值,它在所有请求之间共享它。我还创建了一个静态方法 ( ),它使用自定义连接字符串GetDatabaseConnectionFactory()将 的实例返回到 IoC 容器。OrmLiteConnectionFactory

为了确定连接字符串,我使用了一个请求过滤器,它只读取参数connectionstring。如果未设置,它将使用默认值。然后在集合中设置该值,该RequestContext.Items集合可以通过该GetDatabaseConnectionFactory()方法访问。

请记住,以这种方式暴露连接字符串是危险的,请始终彻底检查任何连接字符串值以确保它们不包含恶意值。即确保他们不尝试连接到管理数据库或不同的服务器,或更改默认设置覆盖等。

在您的 AppHost 中:

服务栈 V3:

public override void Configure(Container container)
{
    container.Register<IDbConnectionFactory>(c => GetDatabaseConnectionFactory()).ReusedWithin(ReuseScope.Request);

    RequestFilters.Add((req,res,obj) => {
        // Default value
        var defaultConnectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;

        // Get the connection string from the connectionstring parameter, or use default
        var dbConnectionString = req.GetParam("connectionstring") ?? defaultConnectionString;

        // You should perform some checks here to make sure the connectionstring isn't something it shouldn't be
        // ...

        // Save the connection string to the HostContext.Instance.Items collection, so we can read it later
        HostContext.Instance.Items.Add("ConnectionString", dbConnectionString);
    });
}

public static IDbConnectionFactory GetDatabaseConnectionFactory()
{
    // Read the connection string from our HostContext Items
    var dbConnectionString = HostContext.Instance.Items["ConnectionString"];

    if(dbConnectionString == null)
        throw new Exception("Connection string has not been set");

    // Return the connection factory for the given connection string
    return new OrmLiteConnectionFactory(dbConnectionString, SqlServerOrmLiteDialectProvider.Instance) {
        ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
    });
}

用途:

using System;
using Funq;
using ServiceStack.ServiceInterface;
using ServiceStack.ServiceHost;
using ServiceStack.WebHost.Endpoints;
using ServiceStack.OrmLite;
using ServiceStack.Common;

服务栈 V4:

public override void Configure(Container container)
{
    container.Register<IDbConnectionFactory>(c => GetDatabaseConnectionFactory()).ReusedWithin(ReuseScope.Request);

    GlobalRequestFilters.Add((req,res,obj) => {
        // Default value
        var defaultConnectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString;

        // Get the connection string from the connectionstring parameter, or use default
        var dbConnectionString = req.GetParam("connectionstring") ?? defaultConnectionString;

        // You should perform some checks here to make sure the connectionstring isn't something it shouldn't be
        // ...

        // Save the connection string to the RequestContext.Items collection, so we can read it later
        HostContext.RequestContext.Items.Add("ConnectionString", dbConnectionString);
    });
}

public static IDbConnectionFactory GetDatabaseConnectionFactory()
{
    // Read the connection string from our Items
    var dbConnectionString = HostContext.RequestContext.Items["ConnectionString"];

    if(dbConnectionString == null)
        throw new Exception("Connection string has not been set");

    // Return the connection factory for the given connection string
    return new OrmLiteConnectionFactory(dbConnectionString, SqlServerOrmLiteDialectProvider.Instance) {
        ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
    });
}

用途:

using System;
using Funq;
using ServiceStack;
using ServiceStack.Data;
using ServiceStack.OrmLite;
using ServiceStack.OrmLite.Sqlite;
于 2014-03-29T10:01:13.187 回答