#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
, и поэтому я не уверен, почему это происходит