Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Base de données de l'opération devrait avoir sur 1 ligne(s) mais effectivement touché 2 ligne(s)

0

La question

J'ai reçu cette erreur une fois que j'ai essayer de mettre à jour le tableau avec la même valeur (carNumber), ma condition est de mettre à jour la date de retour du champ est null.

Pour une raison quelconque, il est de ressembler à la requête de retour de 2 lignes, mais en fait il n'y en a qu'une. Je suis à l'aide de EF. C'est la fonction:

l'erreur d'impression de l'écran

   public void updateStatus(int carNumber1, string acctualDate1)
    {
        DateTime accReturn = DateTime.Parse(acctualDate1);

        var orderCar1 =  db.CarRentalFields.FirstOrDefault(carNum =>
        (carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null));

            orderCar1.ActualReturnDate = accReturn  ;
             
                db.SaveChanges();

L'erreur soulever lors de la tentative de db.saveChanges()

la table de la db, le numéro de la voiture est de 1000 d'impression de l'écran

modelBuilder.Entité pic

s'il vous plaît laissez-moi savoir comment je peux résoudre ce problème.

c# entity-framework linq sql-server
2021-11-23 20:34:34
2
0

problème résolu par l'ajout d'une nouvelle colonne à la car_rental_fields tableau, colonne id qui incluent Identité. si je comprends bien, ici et sur le web, il y a un problème compliqué pk. dans ma solution, l'id n'est pas une clé primaire, mais c'est la logique de linq pour mettre à jour la colonne appropriée. merci pour toutes les personnes participant à cette question.

2021-11-26 20:37:27
0

Cette erreur se produit lors de l'EF ne peut pas résoudre le PK pour votre entité. Dans la plupart des cas pour de simples entités, EF conventions peuvent travailler sur le PK, mais dans votre cas, vous êtes à l'aide d'une clé composite-ci doit donc être configuré. En fonction de comment vous le mappage des entités, vous pouvez le faire soit dans:

  • un EDMX
  • dans le DbContext.OnModelCreating
  • à l'aide d'un EntityTypeConfiguration déclaration
  • à l'aide d'attributs au sein de l'entité elle-même

Puisque nous ne savons pas comment vos entités sont configurés, vous pouvez vérifier ce que la cause en utilisant l'attribut de l'approche au sein de votre entité comme un test. Si vous utilisez un EDMX les classes d'entité sera généré de sorte que vous voulez remplacer avec cette configuration au sein de l'EDMX. (Ne peut pas vraiment vous aider car je n'utilise pas les choses dang :D )

Vous aurez probablement quelque chose comme:

public class CarRentalFields
{
    [Column("start_day")]
    public DateTime StartDay { get; set; }
    [Column("return_date")]
    public DateTime ReturnDate { get; set; }
    [Column("user_id")]
    public int UserId { get; set; }
    [Column("car_number")]
    public DateTime CarNumber { get; set; }
    
    // ... more columns...
}

Vous pouvez même avoir un [Key] l'attribut de l'un de ces domaines, comme CarNumber. Si il y a un PK mappé dans l'entité le problème est qu'il n'est pas assez précis pour identifier de manière unique la ligne. EF va mettre à jour une entité, c'est à vérifier, et s'attendant à mettre à jour qu'une seule ligne dans la table. Il s'agit de trouver plus d'une ligne sera affecté de sorte qu'il échoue.

Ajouter les attributs de la [Key] l'ordre des colonnes de sorte qu'il est reconnu comme une clé composite.

public class CarRentalFields
{
    [Key, Column(Name="start_day", Order=1)]
    public DateTime StartDay { get; set; }
    [Key, Column(Name="return_date", Order=2)]
    public DateTime ReturnDate { get; set; }
    [Key, Column(Name="user_id", Order=3)]
    public int UserId { get; set; }
    [Key, Column(Name="car_number", Order=4)]
    public DateTime CarNumber { get; set; }
    
    // ... more columns...
}

À condition que ces 4 colonnes sont garantis d'être une contrainte unique sur la table, EF sera satisfait quand une seule ligne est mise à jour lorsqu'elle construit elle est mise à JOUR de l'instruction SQL.

A noter encore que si cela fonctionne et si vous utilisez un EDMX, vous aurez besoin d'examiner et de modifier votre EDMX cartographie pour faire les modifications appropriées depuis que la classe d'entité pourrait être régénéré, de perdre votre attributs supplémentaires. (Je crois que le générés classes d'entités à partir d'une EDMX avoir un commentaire d'en-tête pour vous avertir que c'est une classe générée, ce qui est un indicateur à surveiller.)

Mise à jour: Mon principal suspect dans cette serait que la table n'ont pas une correspondance PK définies, soit en cours d'exécution un autre PK combinaison, ou, plus probablement, pas PK compte tenu de la nature de ces champs. EF peut exploités sur les tables qui n'ont pas PK définie, mais elle nécessite une définition de Clé qui assure les enregistrements peuvent être identifiés de manière unique. L'erreur que vous voyez est le cas lorsque la clé de définition n'est pas assez unique. (I. e. si vous êtes à la mise à jour de la voiture 1, et en sélectionnant une ligne: car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 Le problème est que plus d'une ligne a que la combinaison de la DB. Si la DB vous êtes à la vérification de ne pas avoir plus d'une ligne correspondante, alors votre demande est presque certainement pointant vers une autre base de données que vous consultez.

Choses que vous pouvez faire pour vérifier cela:

  1. obtenez de l'exécution de la chaîne de connexion et de voir si elle correspond à la DB vous êtes à la vérification:

Avant d'exécuter votre requête, ajoutez la ligne suivante:

// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
  1. Avoir un regard sur les données vous sont effectivement interrogation:

.

var cars =  db.CarRentalFields.Where(carNum =>
    (carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null)).ToList();

Bien que cette requête peut renvoyer à seulement 1 enregistrement, qui n'est pas la cause du problème. Ce que vous voulez, c'est le CarNumber, date de début, ReturnDate, et nom d'utilisateur pour cet enregistrement:

var car =  db.CarRentalFields
    .Where(carNum => carNum.CarNumber == carNumber1 
        && carNum.ActualReturnDate == null)
    .Select(x => new 
    {
        x.CarNumber,
        x.StartDay,
        x.ReturnDate,
        x.UserId
    }).Single(); // Expect our 1 record here...
var cars = db.CarRentalFields
    .Where(x => x.CarNumber == car.CarNumber
        && x.StartDay == car.StartDay
        && x.ReturnDate == car.ReturnDate
        && x.UserId == car.UserId)
    .ToList(); // Get rows that match our returned Key fields.

Ces requêtes, sélectionnez l'hypothèse de valeurs de clé primaire pour la voiture de l'enregistrement que vous dire de mettre à jour, puis de recherche de voitures pour les enregistrements correspondants avec les attendus de la Clé des champs. Mon argent serait sur que tout en haut de la requête retourne 1 enregistrement, le fond de la requête retourne deux lignes, ce sens alors que seulement 1 enregistrement a un #null ActualReturnDate valeur, votre Clé n'est pas unique, suffisamment pour que le contenu de cette table.

2021-11-26 22:57:48

je suis l'aide de contex, avez-vous vu mon impression de l'écran de l'application model builder?
elirans

Oui, ok c'est à l'aide de la DbContext de OnModelCreating modelBuilder, donc, la Clé est en cours de définition. La prochaine chose à vérifier sera de savoir si ces colonnes correspondent à la PK /w contrainte unique dans votre base de données correspondante. Si non, que peut-être besoin d'être développé. Les clés composites doivent être évités autant que possible comme ils faire la mise en place de relations beaucoup plus de travail. Vous pouvez également utiliser un profiler pour capturer le projet de mise à jour de l'instruction, puis de les convertir en un simple SELECT pour voir ce que les lignes sont retournées. Pour une raison quelconque plus de rangs sont de retour.
Steve Py

Une autre chose à vérifier est de savoir si au moment de l'exécution de l'application est de frapper la même base de données que ce que vous êtes en contrôle. Les données que vous enregistrez peut paraître assez unique si le DB n'est pas l'application d'une contrainte unique sur ces colonnes, mais la base de données d'être souligné lors de l'exécution a des lignes en double.
Steve Py

même erreur se produit à l'aide de votre solution, n'ai-je besoin de changer de fonction? @Steve Py
elirans

Capturer le code SQL généré et exécuté sur la base de données. Je l'utilise généralement un Profiler pour cela, donc pour SQL Server et de SSMS, dans Outils\générateur de profils SQL. Exécuter à l'encontre de votre DB, puis exécuter votre requête. Vous pouvez utiliser un point d'arrêt dans votre application juste avant la SaveChanges, puis désactivez la sortie du générateur de profils avant de reprendre le nettoyage de bruit précédent et de trouver votre instruction de mise à JOUR.
Steve Py

Aussi, vous pouvez poster le concepteur de table de sortie pour votre table? La table ont une réelle PK ensemble avec ces 4 colonnes?
Steve Py

J'ai ajouté à la réponse ci-dessus pour inclure des mesures pour vérifier la chaîne de connexion ainsi que de vérifier dans les données qu'il y a de valeurs de clés dupliquées.
Steve Py

J'ai essayé votre solution. la première chose qu'il a un look comme vous manquez quelque '=' dans les voitures var. deuxième chose - lorsque je tente de faire la mise à jour: voitures.ActualReturnDate = acctualDate1; j'ai eu une erreur cs1061.
elirans

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................