J'ai la méthode ci-dessous et lorsque l'enregistrement des modifications est exécuté, Entity Framework essaie de mettre à jour plus d'une ligne? Même si je ne modifie qu'une date sur un seul enregistrement et que je récupère un enregistrement à modifier.
Erreur
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: l'opération de base de données devrait affecter 1 ligne (s) mais a en fait affecté 2 ligne (s). Les données peuvent avoir été modifiées ou supprimées depuis le chargement des entités.
Méthode
SET NOCOUNT ON; UPDATE [Records_Coworkers] SET [StartDate] = @p0 WHERE [RecordID] = @p1 AND [CoworkerID] = @p2; SELECT @@ROWCOUNT;
D'une manière ou d'une autre, lorsque la requête est exécutée, les paramètres doivent être mis à jour correctement, par exemple. Champ «IsActive». J'ai capturé la requête ci-dessous.
public static async Task<HttpResult> PostRecordCoworkerStartDateAsync(MpidDbContext context, int id, RecordCoworker recordCoworker) { // just testing to see how many are returned int testCount = context.RecordsCoworkers.Where(m => m.Id == id && m.IsActive == true).ToList().Count(); RecordCoworker recordCoworkerToUpdate = context.RecordsCoworkers.SingleOrDefault(m => m.Id == id && m.IsActive == true); recordCoworkerToUpdate.StartDate = recordCoworker.StartDate; try { await context.SaveChangesAsync(); } catch(Exception ex) { var i = ex; } return HttpResult.NoContent; }
en gros, je veux juste mettre à jour le seul enregistrement où «IsActive» est vrai. Mais la requête, car elle supprime la propriété 'IsActive', essaiera de mettre à jour deux ou plusieurs lignes.
3 Réponses :
J'ai découvert pourquoi.
Dans mon entité, j'avais besoin d'ajouter un attribut de données à la propriété 'IsActive'
[Required] [ConcurrencyCheck] public bool IsActive { get; set; }
Juste pour expliquer pourquoi:
SaveChanges
pour signaler à EF qu'il renvoie les modifications à la base de données. Ce sont deux opérations: SELECT
et UPDATE
. Celles-ci sont effectuées séparément car Entity Framework ne sait pas: que faites-vous entre-temps (jusqu'à ce que vous SaveChanges
) à l'entité?
Attribution [ConcurrencyCheck]
à la propriété indique à Entity Framework qu'il devrait veiller à ce que , au moment de la UPDATE
à IsActive
SELECT
UPDATE
de la valeur de la propriété IsActive
devrait être le même que pendant la SELECT
. Lorsqu'il y a différentes applications écrivant dans cette base de données, cela garantit qu'aucune des autres applications n'a changé l'entité pendant la période entre SELECT
et UPDATE
.
Vous devez supprimer la ligne int testCount
. Ou demandez-les comme non suivis.
Dans mon cas, l'erreur a été causée par l'absence de colonne d'identification réelle.
Ce que je croyais être un ID - et configuré dans Entity Framework avec l'attribut [Key] - avait des duplications dans la base de données, donc même je l'ai utilisé pour filtrer j'ai mis à jour plusieurs lignes.