我有一个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)
{
}
}
答案 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();
}