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.