Нарушение дубликата ключа, возникающее даже при заданном состоянии объекта

#c# #sql-server #entity-framework #entity-framework-core #blazor

#c# #sql-сервер #структура организации #сущность-структура-ядро #блейзор

Вопрос:

Я пытаюсь обновить значения элемента проекта, в частности, назначенных пользователям проекта. Функция состоит в том, чтобы иметь возможность удалять пользователей из уже созданного проекта с помощью кнопки редактирования. В приведенной ниже функции я нахожу соответствующий проект, используя переданный идентификатор проекта, а затем нахожу всех пользователей, связанных с проектом. Оттуда я нахожу конкретных пользователей из группы пользователей, связанных с проектом, которые я хочу удалить. Наконец, пользователь удаляется с помощью метода List .Remove (). (Стоимость компании также определяется companyFind и присваивается ее соответствующей стоимости)

AssignedUsersToProject Теперь в нем будут содержаться только пользователи, которые должны быть связаны с проектом один раз .Функция Remove() изменена. Я сделал петлю и настроил их на Unchanged состояние, то же самое относится и к компании.

Однако при сохранении в базе данных для обновления записи отображается следующая ошибка, несмотря на использование неизмененного

 Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.  ---gt; Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_ApplicationUserProject'. Cannot insert duplicate key in object 'dbo.ApplicationUserProject'. The duplicate key value is (5685a830-cb82-4b60-b459-c0852cc74563, 229698cd-eebb-432b-e6eb-08d9b62cc799). The statement has been terminated.  

Как я мог предотвратить это? Я думал, что без изменений запись не будет повторно вставлена в базу данных при обновлении. Был бы признателен за любое понимание этого. Заранее спасибо

Модель проекта

 public class Project  {  [Key]  public Guid ProjectId { get; set; }   public Guid companyID { get; set; }   [Required]  public string ProjectName { get; set; }    public ICollectionlt;ApplicationUsergt; AssignedUsersToProject { get; set; }   public Company assignedCompanyForProject { get; set; }  }  

Модель пользователя приложения

 public class ApplicationUser : IdentityUser {  [JsonIgnore]  public ICollectionlt;Projectgt; Projects { get; set; } }  

Controller function

 [HttpPut("removeUser/{username}/{projectID}")]  public async Tasklt;IActionResultgt; RemoveUserFromProject(string username, Guid projectID)  {   var project = await _context.Projects.FindAsync(projectID);  var query = _context.Users.Where(u =gt; u.Projects.Any(p =gt; p.ProjectId.ToString().Equals(project.ProjectId.ToString()))); //find all users for the project  var companyFind = _context.Companies.First(c =gt; c.CompanyId.ToString().Equals(project.companyID.ToString())); //companyID to current projects company ID   //_context.Attach(project);  project.AssignedUsersToProject = query.ToList();  project.assignedCompanyForProject = companyFind;   var removeUser = query.First(u =gt; u.UserName.Equals(username));  project.AssignedUsersToProject.Remove(removeUser);   foreach (var x in project.AssignedUsersToProject)  {  _context.Entry(x).State = EntityState.Unchanged;  }   _context.Entry(project.AssignedUsersToProject).State = EntityState.Unchanged;  _context.Entry(project.assignedCompanyForProject).State = EntityState.Unchanged;   await _context.SaveChangesAsync();  return NoContent();  }  

Редактировать

Предлагаемые изменения

 [HttpPut("removeUser/{username}/{projectID}")] public async Tasklt;IActionResultgt; RemoveUserFromProject(string username, Guid projectID) {  var project = _context.Projects.Include(u =gt; u.AssignedUsersToProject).FirstOrDefault(p =gt; p.ProjectId.ToString().Equals(projectID.ToString()));  // remove user where username is match project.AssignedUsersToProject.Remove(project.AssignedUsersToProject.First(u =gt; u.UserName == username));  }  

Комментарии:

1. Я не уверен в ошибке, которую вы получаете, но я думаю, что ваше решение здесь слишком сложное для того, чего вы пытаетесь достичь. Например, непонятно, почему вам вообще нужно беспокоиться о компании, поскольку это не имеет отношения к удалению пользователей из проекта. Кроме того, в целом вам не нужно беспокоиться о частом манипулировании EntityState с помощью Entity Framework, так как состояние управляется за вас.

2. Я подумал, что отсутствие компании может привести к какой-то ошибке, поэтому я нашел компанию просто для того, чтобы убедиться, что это не проблема. Я оставил это в сообщении, чтобы убедиться, что это не вызвало проблем.

3. Я бы, вероятно, сначала попытался упростить, а не усложнять. Все, что вам нужно, это что-то вроде: 1) Найдите проект (такой же, как у вас) 2) Найдите соответствующего пользователя в проекте. Назначенный пользовательпроект (при условии, что у вас включена отложенная загрузка, назначенные пользователи будут автоматически загружены из базы данных для вас при повторном просмотре коллекции) 3) Удалите этого пользователя из проекта. Назначенный пользовательпроект 4) _context.SaveChangesAsync()

4. Если это не сработает, у вас могут возникнуть проблемы либо с отображениями, либо с ограничениями в вашей базе данных.

5. Это то, что я сделал, но при попытке SaveChangesAsync() это заканчивается попыткой повторного сохранения оставшихся пользователей, AssignedUsersToProject что вызывает дублирование ключей, но я установил состояние Unchanged , и поэтому я не уверен, почему это происходит