記事詳細


投稿日
2025年11月22日09時17分
タイトル

グイン後に自動的にユーザー専用のデータベース

内容

ログイン後に自動的にユーザー専用のデータベースを作成する仕組み。
これはマルチテナント(ユーザーごとにDBを分ける)に近い構成で、Identity の認証後に EF Core を使って動的に DB を生成する流れになります。

以下は実装の考え方とサンプルコードです。

1. 基本の流れ

  1. ユーザーがログイン成功
  2. ログインしたユーザーの Id または UserName を取得
  3. そのユーザー専用の接続文字列を生成
  4. EF Core の DbContext を使って Database.EnsureCreated() または Migrate() を実行
  5. 必要なら初期データ投入

2. サンプル実装(概念コード)

public class UserSpecificDbContext : DbContext
{
    private readonly string _connectionString;

    public UserSpecificDbContext(string connectionString)
    {
        _connectionString = connectionString;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_connectionString);
    }

    public DbSet<UserData> UserData { get; set; }
}

public class UserDatabaseService
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IConfiguration _config;

    public UserDatabaseService(UserManager<IdentityUser> userManager, IConfiguration config)
    {
        _userManager = userManager;
        _config = config;
    }

    public async Task CreateUserDatabaseAsync(IdentityUser user)
    {
        var baseConn = _config.GetConnectionString("BaseTemplate");
        var userDbName = $"UserDB_{user.Id}";
        var connStr = baseConn.Replace("{DB_NAME}", userDbName);

        using var db = new UserSpecificDbContext(connStr);
        await db.Database.EnsureCreatedAsync();
    }
}

3. ログイン後に呼び出す例

public class AccountController : Controller
{
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly UserManager<IdentityUser> _userManager;
    private readonly UserDatabaseService _dbService;

    public AccountController(
        SignInManager<IdentityUser> signInManager,
        UserManager<IdentityUser> userManager,
        UserDatabaseService dbService)
    {
        _signInManager = signInManager;
        _userManager = userManager;
        _dbService = dbService;
    }

    [HttpPost]
    public async Task<IActionResult> Login(LoginViewModel model)
    {
        var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
        if (result.Succeeded)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            await _dbService.CreateUserDatabaseAsync(user);
            return RedirectToAction("Index", "Home");
        }
        return View(model);
    }
}

4. 注意点

  • DB数が増えると管理コストが高くなる(バックアップ・マイグレーション・接続プールなど)
  • 実運用では「ユーザーごとにスキーマを分ける」か「テーブルでユーザーIDをキーにする」方が一般的
  • Azure SQL や PostgreSQL などでは動的DB作成に権限設定が必要
  • マイグレーションを適用する場合は Migrate() を使うと便利

もし希望があれば、この仕組みを 「ユーザーごとに別スキーマを作る」方式 に書き換えたコード例も作れます。
そちらの方がスケーラブルで運用しやすいですよ。

作りますか?

Powered by Froala Editor

添付画像

画像はありません
Genreのカテゴリ-名
Databases
編集 | 記事一覧