从客户端javascript

时间:2015-05-15 16:30:35

标签: entity-framework asp.net-web-api breeze

我有一个Web API控制器(在我的情况下恰好是Breeze控制器),并且该控制器正在使用Entity Framework进行数据库访问。在设计时,它通过Web.config文件中存在的连接字符串(Conn1)绑定到特定数据库(DB1)。我有两个其他数据库DB2和DB3,它们具有与DB1完全相同的模式但具有不同的数据。我希望能够在浏览器/客户端SPA选择这样做时在运行时切换到不同的数据库DB2或DB3。因此,我想将他的选择作为字符串传递给Web API Controller类(可能是构造函数 - 不知道),然后将其传递给DbContext类的构造函数。但显然这必须在调用控制器的任何操作之前。我不知道可以做些什么。

部分代码如下:

[BreezeController]
public class QuickStaffController : ApiController
{
    //public readonly EFContextProvider<QuickStaffDbContext> _contextProvider = new EFContextProvider<QuickStaffDbContext>();

public readonly EFContextProvider<QuickStaffDbContext> _contextProvider = new EFContextProvider<QuickStaffDbContext>(string connectionStringFromClient);

    [HttpGet]
    public string Metadata()
    {
        return _contextProvider.Metadata();
    }
    [HttpPost]
    public SaveResult SaveChanges(Newtonsoft.Json.Linq.JObject saveBundle)
    {
        return _contextProvider.SaveChanges(saveBundle);
    }
... Action methods


public partial class QuickStaffDbContext : DbContext
{
    public QuickStaffDbContext(string connectionString)
        : base(connectionString)
    {
    }
}

2 个答案:

答案 0 :(得分:1)

WebAPI ApiController个对象会继承Initialize方法,该方法需要HttpControllerContext。从HttpControllerContext,您可以获取请求。如果您可以从请求中的某些信息确定/查找连接字符串,则可以从中创建DbContext。

public EFContextProvider<QuickStaffDbContext> _contextProvider; 

protected override void Initialize(HttpControllerContext controllerContext)
{
    var request = controllerContext.Request;
    var path = request.RequestUri.AbsolutePath;
    string connectionString;
    if (path.StartsWith("/breeze/db2/") {
        connectionString = Db2ConnectionString; // perform a lookup somehow
    } else {
        connectionString = Db1ConnectionString;
    }

    _contextProvider = new EFContextProvider<QuickStaffDbContext>(string connectionString);
}

一旦你知道要构建什么字符串,就可以在Steve Greene的答案中使用这种技术来构建连接字符串。

答案 1 :(得分:0)

如果是SQL,请尝试使用SQLConnectionStringBuilder,并在这些方面有一些变化:

public partial class QuickStaffDbContext : DbContext
{
    public QuickStaffDbContext()
        : base(MyConnectionString())
    {
    }
}

private static string MyConnectionString()
{
    SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
    string datasource = {... aply your logic }
    sqlBuilder.DataSource = datasource;
    sqlBuilder.InitialCatalog = "YYY";
    sqlBuilder.PersistSecurityInfo = true;
    sqlBuilder.IntegratedSecurity = true;
    sqlBuilder.MultipleActiveResultSets = true;

    return sqlBuilder.ToString();
}