我在从头创建新用户(注册)和从已登录的用户中创建新用户时遇到了一种奇怪的行为,它不依赖于底层的数据库(在这种情况下,我使用的是postgreSQL)。
但首先,这里是它们之间的关系:
![Tables relationships](https://istack.dev59.com/gAQBK.webp)
现在,在注册和登录时,我都使用UserManager
来创建用户。
首先,我创建一个新的UserSetting
,进行SaveChanges()
,然后将新创建实体的Id
值分配给AppUser
属性UserSettingId
。
这就是它失败的地方,具体取决于您是否已注册并登录的用户或者是新注册的用户,代码没有改变:
var userSettings = await _userService.UserSettings.AddAsync(new UserSettings
{
LanguageId = langId,
ThemeId = themeId
});
//wrapper to the Context.SaveChangesAsync()
//failure point!
if (!await _userService.SaveChangesAsync<bool>())
在创建一个已登录用户的新用户时,异常错误(exception error)提到了一个
PK_LanguageId
已经存在,就好像我正在创建一个新的Language实体,但是,正如您所看到的,我只是将默认的langId
分配给了新的UserSetting
。以下是异常截图:![enter image description here](https://istack.dev59.com/SbYn8.webp)
Languages
中出现了重复键,就好像它还试图插入一个新的Language
实体。在
Startup
中注册的服务(_userService
)是瞬态的。以下是模型类及其在
OnModelCreating
中的配置:public class AppUser : IdentityUser
{
public long UserSettingsId { get; set; }
public virtual UserSettings UserSettings { get; set; }
//...other properties
}
public class UserSettings
{
public long Id { get; set; }
public int LanguageId { get; set; }
public virtual Language Language { get; set; }
public int ThemeId { get; set; }
public virtual Theme Theme { get; set; }
public virtual AppUser AppUser { get; set; }
}
public class Theme
{
[Key]
public int Id { get; set; }
[StringLength(10)]
public string Type { get; set; }
}
public class Language
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
[MaxLength(2)]
public string Code { get; set; }
}
builder.Entity<AppUser>().HasKey(u => u.Id);
builder.Entity<AppUser>().HasOne(u => u.UserSettings).WithOne(us => us.AppUser);
builder.Entity<UserSettings>().HasKey(us => us.Id);
builder.Entity<UserSettings>().Property(us => us.Id).ValueGeneratedOnAdd();
builder.Entity<UserSettings>().HasOne(us => us.Language);
builder.Entity<UserSettings>().HasOne(us => us.Theme);
我做错了什么?为什么它的行为如此不同?有没有从已登录用户创建用户的其他方法?
SaveChangesAsync
时,您将保存上下文中已完成的所有更改,因此可能是这样。 - Sergey Kudriavtsev