【问题标题】:MVC EF-Code First Approach: Create New Database?MVC EF 代码优先方法:创建新数据库?
【发布时间】:2017-04-26 07:14:03
【问题描述】:

我正在处理一个项目,我被要求对应用程序进行编程,以便为每个注册到应用程序的新用户自动创建新数据库。

【问题讨论】:

  • 不确定代码优先是否会帮助您。每次用户注册时执行一个简单的 SQL CREATE DATABASE 脚本会更容易。
  • 是否可以使用两个DbContext 类,一个作为“主”来保留用户,另一个将根据登录用户使用连接字符串创建?您可以使用生成的连接字符串在控制器的Register 操作中创建数据库。
  • @ArmaanLabib 您不需要 100 个 DbContext 类,但您可以使用不同的连接字符串实例化同一个类。请参阅我添加的答案。

标签: asp.net-mvc


【解决方案1】:

您可以定义两个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" />

在用户创建成功后AccountControllerRegister动作中,可以使用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

【讨论】:

  • @ArmaanLabib 在EmployeeController 中(假设你是这样命名的),看看你是如何实例化上下文的。应该就像我在帖子中提到的那样:MyDbContext context = new MyDbContext(string.Format(baseConnectionString, "MyApplicationDB_" + User.Identity.GetUserId())); ,如果您在context.Employees 中添加实体,它会将它们插入正确的数据库中。
  • @ArmaanLabib 确保您调用变量baseConnectionString,就像我在我的答案(来自ConfigurationManager)中分配的那样,而不是字符串"baseConnectionString"。什么是抛出空引用异常?
  • 这可能是因为您在登录后立即调用它。这个问题可能会对您有所帮助:stackoverflow.com/q/33951881/2685912。基本上它说您可以在后续请求中以这种方式检索用户 ID,但不是您正在登录的用户正在执行的同一请求。
【解决方案2】:

你只需要删除你的连接字符串

1:如果您没有任何迁移,则添加一个

1:启用迁移

2:添加迁移初始迁移

3:更新数据库

如果您已经有可用的迁移,只需使用

1:更新数据库

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多