SaveChangesAsync 失败,分配的用户反对 AspNetUsers 重复键冲突
SaveChangesAsync fails with assigned users to object AspNetUsers duplicate key violation
我正在尝试创建一个项目项,其中一个项目可以有多个用户。您可以通过输入用户名并按下按钮来分配用户;控制器将找到用户和 return 用户(如果存在)。然后将它们添加到列表中,然后在项目创建提交时将其分配给项目。当 POST 参与项目时,SaveChangesAsync() 会生成带有错误的 http 响应 500:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_AspNetUsers'. Cannot insert duplicate key in object 'dbo.AspNetUsers'. The duplicate key value is (fa2f3cdf-6147-4973-9c1e-988a21408610).
The statement has been terminated.
我似乎无法弄清楚为什么会发生这种情况,我觉得表单被提交了两次,或者 Editform 通过这两个按钮提交的方式不正确。我对 Blazor 和 EF 还很陌生,所以如果能深入了解可能导致此问题的原因以及我可能如何解决此问题,我将不胜感激。提前致谢
创建剃须刀页面
<EditForm Model="@projectItem" OnValidSubmit="@CreateNewProject">
<DataAnnotationsValidator />
<div class="form-group">
<label class="custom-control-label"> Name </label>
<InputText id="title" @bind-Value="projectItem.ProjectName" class="form-control" />
<InputText id="title" @bind-Value="projectItem.ProjectDescription" class="form-control" />
<ValidationMessage For="@(() => projectItem.ProjectName)" />
<button type="submit" class="btn btn-primary">Create Project</button>
</div>
<ValidationSummary />
</EditForm>
<EditForm Model="@AssignUser" OnValidSubmit="@AddUserToProject">
<DataAnnotationsValidator />
<div class="form-group">
<label class="custom-control-label"> Assign users </label>
<InputText id="title" type="email" @bind-Value="@AssignUser.UserName" class="form-control" />
<button type="submit" class="btn btn-primary">Add User</button>
</div>
</EditForm>
<p> Currently assigned users </p>
@if (ListOfAllUsers.Count() == 0)
{
<p> No users assigned yet</p>
}
else
{
@for(int i = 0; i < ListOfAllUsers.Count(); i++)
{
<li> @ListOfAllUsers[i].UserName </li>
}
}
private Project projectItem { get; set; } = new Project();
private ApplicationUser AssignUser { get; set; } = new ApplicationUser();
private List<ApplicationUser> ListOfAllUsers { get; set; } = new List<ApplicationUser>();
//submit and create project with the assigned users
private async void CreateNewProject()
{
projectItem.AssignedUsersToProject = ListOfAllUsers;
try
{
var response = await Http.PostAsJsonAsync("Projects", projectItem);
var content = await response.Content.ReadAsStringAsync();
var project = JsonConvert.DeserializeObject<Project>(content);
if(response.IsSuccessStatusCode)
Navigation.NavigateTo($"/projects");
}
catch (Exception e)
{
}
}
// find and add user
private async void AddUserToProject()
{
try
{
var response = await Http.PostAsJsonAsync($"Projects/{AssignUser.UserName}", AssignUser);
var content = await response.Content.ReadAsStringAsync();
var userobject = JsonConvert.DeserializeObject<ApplicationUser>(content);
if (response.IsSuccessStatusCode)
{
if (!ListOfAllUsers.Any(n => n.UserName.Equals(userobject.UserName)))
{
ListOfAllUsers.Add(userobject);
} else
{
AssignUser.UserName = "This user is already added to the project.";
}
} else if (!response.IsSuccessStatusCode)
{
AssignUser.UserName = "User not found, try again";
}
}
catch (Exception e)
{
}
}
控制器:创建项目
[HttpPost]
public async Task<ActionResult<Project>> PostProject(Project project)
{
_context.Projects.Add(project);
await _context.SaveChangesAsync(); // error occurs when reaching this point
return CreatedAtAction("GetProject", new { id = project.ProjectId }, project);
}
控制器:查找和 return 用户
[HttpPost("{userEmail}")]
public async Task<ActionResult<ApplicationUser>> AddUserToProject(string userEmail)
{
try
{
// Find user
ApplicationUser userValid = _userManager.Users.Where
(s => s.Email == userEmail).First();
return userValid;
}
catch (InvalidOperationException)
{
return BadRequest();
}
}
型号
public class Project
{
[Key]
public Guid ProjectId { get; set; }
[Required]
public string ProjectName { get; set; }
[JsonIgnore]
public ICollection<ApplicationUser> AssignedUsersToProject { get; set; }
public Company assignedCompanyForProject { get; set; }
}
public class ApplicationUser : IdentityUser
{
public string firstName { get; set; }
public string lastName { get; set; }
[JsonIgnore]
public ICollection<Project> Projects { get; set; }
}
表格图片
您键入要添加到项目中的用户的名称,然后单击“添加用户”,如果他们是存在的用户,则会找到并 return 用户(这不会创建项目,但只会找到用户) .然后将该用户添加到 ListOfAllUsers 列表,然后循环显示所有当前分配的用户。一旦在相关用户旁边给出了项目名称和描述,则应按下“创建项目”按钮,这将创建具有已确定的分配用户的整个项目。这是什么提交到数据库添加一个新的Project项
建议的更改
实施EntityState.Unchanged;
foreach(var x in project.AssignedUsersToProject)
{
_context.Entry(x).State = EntityState.Unchanged;
}
_context.Projects.Add(project);
导致以下错误:
ystem.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32
创建项目时在控制器中执行以下操作解决了问题。
foreach(var x in project.AssignedUsersToProject)
{
_context.Entry(x).State = EntityState.Unchanged;
}
_context.Projects.Add(project);
我正在尝试创建一个项目项,其中一个项目可以有多个用户。您可以通过输入用户名并按下按钮来分配用户;控制器将找到用户和 return 用户(如果存在)。然后将它们添加到列表中,然后在项目创建提交时将其分配给项目。当 POST 参与项目时,SaveChangesAsync() 会生成带有错误的 http 响应 500:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_AspNetUsers'. Cannot insert duplicate key in object 'dbo.AspNetUsers'. The duplicate key value is (fa2f3cdf-6147-4973-9c1e-988a21408610).
The statement has been terminated.
我似乎无法弄清楚为什么会发生这种情况,我觉得表单被提交了两次,或者 Editform 通过这两个按钮提交的方式不正确。我对 Blazor 和 EF 还很陌生,所以如果能深入了解可能导致此问题的原因以及我可能如何解决此问题,我将不胜感激。提前致谢
创建剃须刀页面
<EditForm Model="@projectItem" OnValidSubmit="@CreateNewProject">
<DataAnnotationsValidator />
<div class="form-group">
<label class="custom-control-label"> Name </label>
<InputText id="title" @bind-Value="projectItem.ProjectName" class="form-control" />
<InputText id="title" @bind-Value="projectItem.ProjectDescription" class="form-control" />
<ValidationMessage For="@(() => projectItem.ProjectName)" />
<button type="submit" class="btn btn-primary">Create Project</button>
</div>
<ValidationSummary />
</EditForm>
<EditForm Model="@AssignUser" OnValidSubmit="@AddUserToProject">
<DataAnnotationsValidator />
<div class="form-group">
<label class="custom-control-label"> Assign users </label>
<InputText id="title" type="email" @bind-Value="@AssignUser.UserName" class="form-control" />
<button type="submit" class="btn btn-primary">Add User</button>
</div>
</EditForm>
<p> Currently assigned users </p>
@if (ListOfAllUsers.Count() == 0)
{
<p> No users assigned yet</p>
}
else
{
@for(int i = 0; i < ListOfAllUsers.Count(); i++)
{
<li> @ListOfAllUsers[i].UserName </li>
}
}
private Project projectItem { get; set; } = new Project();
private ApplicationUser AssignUser { get; set; } = new ApplicationUser();
private List<ApplicationUser> ListOfAllUsers { get; set; } = new List<ApplicationUser>();
//submit and create project with the assigned users
private async void CreateNewProject()
{
projectItem.AssignedUsersToProject = ListOfAllUsers;
try
{
var response = await Http.PostAsJsonAsync("Projects", projectItem);
var content = await response.Content.ReadAsStringAsync();
var project = JsonConvert.DeserializeObject<Project>(content);
if(response.IsSuccessStatusCode)
Navigation.NavigateTo($"/projects");
}
catch (Exception e)
{
}
}
// find and add user
private async void AddUserToProject()
{
try
{
var response = await Http.PostAsJsonAsync($"Projects/{AssignUser.UserName}", AssignUser);
var content = await response.Content.ReadAsStringAsync();
var userobject = JsonConvert.DeserializeObject<ApplicationUser>(content);
if (response.IsSuccessStatusCode)
{
if (!ListOfAllUsers.Any(n => n.UserName.Equals(userobject.UserName)))
{
ListOfAllUsers.Add(userobject);
} else
{
AssignUser.UserName = "This user is already added to the project.";
}
} else if (!response.IsSuccessStatusCode)
{
AssignUser.UserName = "User not found, try again";
}
}
catch (Exception e)
{
}
}
控制器:创建项目
[HttpPost]
public async Task<ActionResult<Project>> PostProject(Project project)
{
_context.Projects.Add(project);
await _context.SaveChangesAsync(); // error occurs when reaching this point
return CreatedAtAction("GetProject", new { id = project.ProjectId }, project);
}
控制器:查找和 return 用户
[HttpPost("{userEmail}")]
public async Task<ActionResult<ApplicationUser>> AddUserToProject(string userEmail)
{
try
{
// Find user
ApplicationUser userValid = _userManager.Users.Where
(s => s.Email == userEmail).First();
return userValid;
}
catch (InvalidOperationException)
{
return BadRequest();
}
}
型号
public class Project
{
[Key]
public Guid ProjectId { get; set; }
[Required]
public string ProjectName { get; set; }
[JsonIgnore]
public ICollection<ApplicationUser> AssignedUsersToProject { get; set; }
public Company assignedCompanyForProject { get; set; }
}
public class ApplicationUser : IdentityUser
{
public string firstName { get; set; }
public string lastName { get; set; }
[JsonIgnore]
public ICollection<Project> Projects { get; set; }
}
表格图片
建议的更改
实施EntityState.Unchanged;
foreach(var x in project.AssignedUsersToProject)
{
_context.Entry(x).State = EntityState.Unchanged;
}
_context.Projects.Add(project);
导致以下错误:
ystem.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32
创建项目时在控制器中执行以下操作解决了问题。
foreach(var x in project.AssignedUsersToProject)
{
_context.Entry(x).State = EntityState.Unchanged;
}
_context.Projects.Add(project);