【发布时间】:2021-03-23 21:26:03
【问题描述】:
我有两个表,一个是身份表 aspnetuser,另一个是我现在创建的用户表,aspnetuser 中的一列是自动生成的身份列,这是 aspnetuser 表中的外键和最终创建的用户表中的主键一对一的关系。
现在我有这个需要,我想同时在这两个表中插入,所以如果在 aspnetuser 中创建记录成功但在用户表中创建记录失败后,我需要回滚更改。
我怎样才能做到这一点?因为现在await _userManager.CreateAsync(user, Input.Password);
这段代码一被调用就进入 aspnetuser 表中的记录...
我在这里找到了类似的东西How to create transaction with asp.net identity? 但无法理解它,因为在我的情况下,aspnetuser 表有一个 U_ID 列,它是由 db 生成的标识列,我需要获取它的值才能在用户表中创建新记录
有可能吗?
这是图表
one-one relation
这是应用程序用户
public class ApplicationUser : IdentityUser
{
[PersonalData]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int U_ID { get; set; }
}
更新 正如@Zhi Lv 所说,我试过这个
returnUrl ??= Url.Content("~/");
var result = false;
var errorlist = new List<IdentityError>();
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
var user = new ApplicationUser();
if (ModelState.IsValid)
{
using (var transaction = _dbcontext.Database.BeginTransaction())
{
try
{
Guid guid = Guid.NewGuid();
ShortGuid sguid1 = guid;
//insert user to Users table.
var customeruser = new OnlineEarning.Core.DataModel.Models.User()
{
Name = Input.UserName,
Password = Input.Password,
Email = Input.Email,
UserRefNo = sguid1,
EasyPaisaNoJazzCashNo = "2214457896",
PhoneNo = "2214457896",
City = "Rwp",
};
_dbcontext.Users.Add(customeruser);
_dbcontext.SaveChanges();
//get the latest user id.
var u_id = customeruser.Id;
//
user = new ApplicationUser { UserName = Input.Email, Email = Input.Email, U_ID = u_id };
var saveresult = await _userManager.CreateAsync(user, Input.Password);
if (saveresult.Succeeded)
result = true;
else
errorlist = saveresult.Errors.ToList();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
}
if (result)
{
//do something
}
foreach (var error in errorlist)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
但现在我得到了这个异常'Execution TImeout expired'
更新 2 现在我可以使用以下代码在单个事务中创建事务并在两个表中输入记录
try
{
returnUrl ??= Url.Content("~/");
var result = false;
var errorlist = new List<IdentityError>();
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
var user = new ApplicationUser();
if (ModelState.IsValid)
{
using (TransactionScope transaction = new TransactionScope(System.Transactions.TransactionScopeAsyncFlowOption.Enabled))
{
try
{
Guid guid = Guid.NewGuid();
ShortGuid sguid1 = guid;
//insert user to Users table.
var customeruser = new OnlineEarning.Core.DataModel.Models.User()
{
Name = Input.UserName,
Password = Input.Password,
Email = Input.Email,
UserRefNo = sguid1,
EasyPaisaNoJazzCashNo = "01224457854",
PhoneNo = "01224457854",
City = "Rwp",
};
_dbcontext.Users.Add(customeruser);
_dbcontext.SaveChanges();
//get the latest user id.
var u_id = customeruser.Id;
user = new ApplicationUser { UserName = Input.Email, Email = Input.Email, U_ID = u_id };
var saveresult = await _userManager.CreateAsync(user, Input.Password);
if (saveresult.Succeeded)
{
result = true;
var uservs = await _userManager.FindByEmailAsync(Input.Email);
await _signInManager.SignInAsync(user, isPersistent: false);
var userv = await _userManager.FindByEmailAsync(Input.Email);
}
else
errorlist = saveresult.Errors.ToList();
transaction.Complete();
}
catch (Exception ex)
{
transaction.Dispose();
ModelState.AddModelError(string.Empty, ex.InnerException.Message.ToString());
}
}
if (result)
{
//do something
}
foreach (var error in errorlist)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
catch(Exception ex)
{
return Page();
}
但在调试过程中,我发现在调试中启动事务时,我无法读取或写入 sql server 中的两个表。现在我的问题是,如果两个用户尝试同时注册怎么办?只有一个其中一个是允许的,另一个会出现异常?如果是,那么在这种情况下该怎么办……离场交易是不能避免的,否则数据会不一致
【问题讨论】:
标签: asp.net-core transactions asp.net-identity