If I have 2 DBs (with the exact same schema meaning each DB has only the Identity tables) and 2 Contexts (one for each DB), and I run the project to add users, for example, which DB will be used to insert such users? or How do I tell my project to add users to DB1 or DB2?
Maybe this is a basic question but I am not a EF expert, I am using it only because it is required by Identity.
Do you mean in your project, you want to use Asp.net core Identity with 2 Dbcontexts (one for each DB)? As far as I know, if add Identity twice, it will show the "InvalidOperationException: Scheme already exists: Identity.Application" error when running the application.
So, to manage the Identity tables from two database, as a workaround, you can try to use Identity with the first or second DbContext, then for the other DbContext, you can directly access the related Identity tables via the DbContext, instead of via the Asp.net core Identity (using the UserManager or RoleManager).
Code like this:
Program.cs:
//register two dbcontexts, one for each DB
var firstDbconnectionString = builder.Configuration.GetConnectionString("FirstDbConnection");
var secondDbconnectionString = builder.Configuration.GetConnectionString("SecondDbConnection");
builder.Services.AddDbContext<FirstDbContext>(options =>
options.UseSqlServer(firstDbconnectionString));
builder.Services.AddDbContext<SecondDbContext>(options =>
options.UseSqlServer(secondDbconnectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
//select one dbContext and confire the Identity.
builder.Services.AddDefaultIdentity<FirstDbAppUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<FirstDbContext>();
When use the Identity and SecondDbContext, the code like this:
Register.cshtml.cs:
public class RegisterModel : PageModel
{
//Use Identity with First DBContext.
private readonly SignInManager<FirstDbAppUser> _firstDbsignInManager;
private readonly UserManager<FirstDbAppUser> _firstDbuserManager;
private readonly IUserStore<FirstDbAppUser> _firstDbuserStore;
private readonly IUserEmailStore<FirstDbAppUser> _firstDbemailStore;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
#region
//use the second DbContext.
private readonly SecondDbContext _senddbcontext;
private readonly IPasswordHasher<FirstDbAppUser> _passwordHasher;
#endregion
public RegisterModel(
UserManager<FirstDbAppUser> userManager,
IUserStore<FirstDbAppUser> userStore,
SignInManager<FirstDbAppUser> signInManager,
ILogger<RegisterModel> logger,
SecondDbContext secondDbContext,
IPasswordHasher<FirstDbAppUser> passwordHasher,
IEmailSender emailSender)
{
_firstDbuserManager = userManager;
_firstDbuserStore = userStore;
_firstDbemailStore = GetEmailStore();
_firstDbsignInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
_senddbcontext = secondDbContext;
_passwordHasher = passwordHasher;
}
and
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _firstDbsignInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = CreateUser();
await _firstDbuserStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
await _firstDbemailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
//Create user in the SecondDb using SecondDbContext.
_senddbcontext.Users.Add(new SecondDbAppUser() { UserName = user.UserName, PasswordHash = _passwordHasher.HashPassword(user, Input.Password) });
_senddbcontext.SaveChanges();
//create user in the FirstDb using Identity.
var result = await _firstDbuserManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
...
Then, after register an new user the result like this:
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion