您可以定义两个DbContext 类,一个是存储用户的数据库(称为ApplicationDbContext,它扩展了IdentityDbContext),另一个可以是自定义数据库上下文(称为MyContext)。
Appart 从ApplicationDbContext 使用的DefaultConnection 中添加一个基本连接字符串,在Web.config 中可能是这样的(注意{0},然后您可以在string.Format() 中使用它):
<add name="BaseConnectionString" connectionString="Data Source=(local)\SQLEXPRESS;Initial Catalog={0};Integrated Security=True"
providerName="System.Data.SqlClient" />
在用户创建成功后AccountController的Register动作中,可以使用BaseConnectionString生成的连接字符串和创建用户的Id创建一个新的db上下文实例。
string baseConnectionString = ConfigurationManager.ConnectionStrings["BaseConnectionString"].ConnectionString;
MyDbContext newContext = new MyDbContext(string.Format(baseConnectionString, "MyApplicationDB_" + user.Id));
然后使用某些东西来触发数据库创建(如果它不存在),例如
var user = newContext.Posts.FirstOrDefault(); // Assuming you have a DbSet<Posts> there
使用如下定义的构造函数,如果数据库尚不存在,它将创建数据库,并且数据库名称将是唯一的,因为用户 ID 是例如MyApplicationDB_9b8cd172-7a3a-4a09-965a-2204e97bc850。在这里,您还可以执行任何其他逻辑,例如插入一些数据,这些数据将用作新创建的数据库的上下文数据。
我用于MyDbContext的构造函数将连接字符串作为参数并调用基本构造函数,如果它不存在,则必须对其进行初始化以创建数据库。
public MyDbContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>());
}
现在,在您的控制器中,您始终可以使用 MyContext 的实例来查询数据库实体,并在实例化它时,根据登录的用户 ID 提供连接字符串。
string baseConnectionString = ConfigurationManager.ConnectionStrings["BaseConnectionString"].ConnectionString;
MyDbContext context = new MyDbContext(string.Format(baseConnectionString, "MyApplicationDB_" + User.Identity.GetUserId())); // make sure you are using Microsoft.AspNet.Identity for this
var entitiesOfThisUserDb = context.Posts.ToList(); // Fetches the posts in the database we created for the logged in user