![](/img/trans.png)
[英]EF update ApplicationUser(inherit from IdentityUser) with many to many relationship collections
[英]Can't update IdentityUser - double SQL update
I've got an angular website with Mvc's REST Api. I have just updated it from .net core 2.0 to the newest .Net 6, along with EF Core and AspNetCore.Identity.
I have an extended the AspNetCore's IdentityUser. When I try to update it, there are 2 update requests sent (I found that out using the Sql Server Profiler) - one containing the updated column and the another one resetting it back to the original value. It happens only to the IdentityUser, other entities work normally. As a result, I can't update any user.
They can occasionally come in different order so sometimes the update does work (but more often doesn't).
e.g. when I try something like this
var user = await UserAccountManager.UserManager.FindByIdAsync(id);
user.Name = model.Name;
var result = await UserAccountManager.UserManager.UpdateAsync(user);
After this I would see something like this in the profiler:
As you can see, there are 2 subsequent updates which differ by the Name field and the ConcurrencyStamp.
I've tried to just fetch the user directly from the context e.g.:
var xx = await Context.Users.SingleOrDefaultAsync(m => m.Id == id);
xx.Name = model.Name;
var aa = await Context.SaveChangesAsync();
Same thing.
Even wrapping it all in a transaction didn't work - the SQL requests are separated out but after updating the user there is still another SQL query sent that reverts it back.
I'm pasting in the ConfigureServices function (from Startup.cs) if that helps:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson(options => {
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
services.AddDbContext<OffWorkDbContext>(options =>
{
options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"], b => b.MigrationsAssembly("Hicron.OffWorkPlanner.DataAccessComponent"));
});
// add identity
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<OffWorkDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(o =>
{
// User settings
o.User.RequireUniqueEmail = true;
o.Password.RequireDigit = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequireUppercase = false;
o.Password.RequireLowercase = false;
//o.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
//o.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
//o.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Token:Issuer"],
ValidAudience = Configuration["Token:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Token:Key"]))
};
});
services.AddAuthorization(options =>
{
//add authorization policies
options.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
Mapper.Initialize(cfg =>
{
cfg.AddProfile<AutoMapperProfile>();
});
// Add cors
services.AddCors();
// Add framework services.
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
});
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.Configure<EmailConfig>(Configuration.GetSection("SmtpConfig"));
services.AddScoped<IEmailNotifications, EmailNotifications>();
services.AddScoped<IUserAccountManager, UserAccountManager>();
services.AddScoped<ITeamService, TeamService>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<IDayService, DayService>();
services.AddScoped<IProjectService, ProjectService>();
services.AddScoped<IUserCalendarItemService, UserCalendarItemService>();
services.AddScoped<IDepartmentService, DepartmentService>();
services.AddTransient<IDatabaseInitializer, DatabaseInitializer>();
}
Please help me figure out what's going on here (and update the user).
好的,事實證明有 2 個並發請求 - 第 2 個是更新角色,即使角色沒有明確更新用戶,它確實在后台更改了並發時間戳,並且出於某種原因它正在這樣做過時的價值觀。
為了解決這個問題,我們只是將這兩個請求放在一起。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.