Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: baza de Date operațiune de așteptat să afecteze 1 row(s), dar de fapt afectate 2 row(s)

0

Problema

Am primit aceasta eroare o dată am încerca să actualizeze tabelul cu aceeași valoare (carNumber), starea mea este de a actualiza în cazul în care rentabilitatea reală data câmpul este nul.

Pentru anumite motive se arata ca interogarea întoarce 2 rânduri, dar de fapt este doar unul. Eu sunt, folosind EF. Aceasta este funcția:

eroarea - print screen

   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();

Eroarea crește atunci când încearcă să-db.saveChanges()

tabel din db, numărul de mașini este de 1000 - print screen

modelBuilder.Entitate pic

te rog, lasă-mă să știu cum pot rezolva aceasta problema.

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

am rezolvat problema de a adăuga o nouă coloană la car_rental_fields masă, id coloană care include Identitatea. după cum am înțeles de aici și de pe web, există o problemă cu complicată pk. în soluție id-ul nu este o cheie primară, dar este logica pentru linq pentru a actualiza corect coloana. mulțumiri pentru toți oamenii care se implică în această problemă.

2021-11-26 20:37:27
0

Această eroare apare atunci când EF nu poate rezolva PK pentru entitate. În cele mai multe cazuri pentru entităților simple, EF convențiile de la PK, dar în cazul în care utilizați un compozit cheie, astfel încât aceasta trebuie să fie configurat. În funcție de modul în care sunt cartografiere entități puteți face acest lucru fie:

  • o EDMX
  • în DbContext.OnModelCreating
  • folosind un EntityTypeConfiguration declarația
  • folosind atribute în cadrul entității în sine

Deoarece nu știm cum entități sunt configurate, puteți verifica acest lucru ca fiind cauza folosind atributul abordare în cadrul entității ca un test. Dacă utilizați un EDMX entitatea clase vor fi generate astfel încât veți dori să le înlocuiască cu configurație în EDMX. (Nu poate într-adevăr ajuta pentru ca eu nu folosesc dang lucruri :D )

Va trebui, probabil, ceva de genul:

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...
}

Poate chiar ai o [Key] atribut pe unul din aceste domenii, cum ar fi CarNumber. Dacă există un PK mapate în entitate problema este că nu este suficient de specifice pentru a identifica în mod unic rând. Când EF merge pentru a actualiza o singură entitate, este verificarea, și așteaptă să actualizați doar un rând în tabel. E găsirea mai mult de un rând vor fi afectate astfel încât acesta nu reușește.

Adăugați atribute pentru [Key] cu coloana scopul de aceea este recunoscut ca un compozit cheie.

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...
}

Cu condiția ca aceste 4 coloane sunt garantate a fi o constrângere unică pe masă, EF va fi mulțumit, atunci când doar un singur rand este actualizat atunci când se construiește o ACTUALIZARE declarație SQL.

Rețineți că dacă acest lucru funcționează și utilizați un EDMX, veți avea nevoie de a revizui și modifica EDMX de cartografiere pentru a face modificările corespunzătoare din acea clasă de entități ar putea fi regenerat, pierde în plus atribute. (Cred că a generat clase entitate de la o EDMX un comentariu antet te avertizez că este un generat de clasă, astfel încât este un indicator pentru a viziona afară pentru.)

Update: Mi principalul suspect ar fi că tabelul nu are de fapt o potrivire PK definite, fie o altă PK combinație, sau mai probabil nu PK având în vedere natura acestor domenii. EF poate operate pe mese care nu au PK definite, dar e nevoie de o Cheie de definire care asigură înregistrările pot fi identificate în mod unic. Eroarea vedeți se întâmplă atunci când cheia definiție nu este destul de unic. (I. e. dacă sunteți actualizarea masina 1, și selectarea unui rând care are: car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 problema este că mai mult de un rând are combinația în DB. Dacă DB sunteți de verificare nu au mai mult de o potrivire rând, atunci cererea dumneavoastră este aproape sigur îndreptat spre o altă bază de date decât sunteți de verificare.

Lucruri pe care le puteți face pentru a verifica acest lucru:

  1. obține runtime șir de conexiune și a vedea dacă se potrivește DB sunteți de verificare:

Înainte de a alerga interogare, se adaugă următoarele:

// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
  1. Avea o privire la datele pe care le sunt de fapt interogarea:

.

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

În timp ce această interogare ar putea reveni doar 1 record, care nu este cauza problemei. Ceea ce vrei este CarNumber, StartDate, ReturnDate, și nume de Utilizator pentru acest album:

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.

Aceste interogări selectați presupune PK valorile pentru masina record adică să-l actualizați, apoi masini de căutare pentru înregistrările se potrivesc cu temperatura domenii Cheie. Banii mei ar fi pe faptul că în timp ce partea de sus interogare returnează 1 record, în partea de jos interogare returnează două rânduri, adică în timp ce doar 1 de înregistrare a o #nul ActualReturnDate valoare, Cheia nu este destul de unic pentru conținutul acestui tabel.

2021-11-26 22:57:48

eu sunt, folosind contex, nu mi-ai vazut print screen de model builder?
elirans

Da, ok asta e, folosind DbContext e OnModelCreating modelBuilder, astfel încât Cheia este de a fi definite. Următorul lucru de verificat va fi dacă aceste coloane se potrivesc PK /w constrângere unică în bază de date corespunzătoare. Dacă nu, cheia poate fi necesar să fie extins. Compozit cheile ar trebui să fie evitate pe cât posibil ca ei fac configurarea relații mult mai mult de lucru. Puteți folosi, de asemenea, un profiler pentru a captura propunerea de actualizare declaratie, apoi converti într-un simplu SELECTAȚI pentru a vedea ce randurile sunt returnate. Pentru un anumit motiv mai mult de o randuri vin înapoi.
Steve Py

Un alt lucru pentru a verifica dacă este în execuție aplicația este lovit de aceeași bază de date ca ceea ce sunt de verificare. Datele sunt de verificare ar putea să apară destul de unic dacă DB este nu impune o constrângere unică pe acele coloane, dar date fiind indicat la runtime a rândurilor duplicate.
Steve Py

aceeasi eroare să apară folosind solutia ta, am nevoie pentru a schimba funcția, de asemenea,? @Steve Py
elirans

Captura SQL generat și condusă pe bază de date. Eu de obicei folosesc un Psiholog pentru asta, așa că pentru SQL Server și SSMS, sub Instrumente\SQL Profiler. Rula împotriva DB, apoi executați interogarea. Puteți utiliza un punct de întrerupere în cererea dumneavoastră chiar înainte de SaveChanges, atunci clar profiler de ieșire înainte de reluarea pentru a curăța anterior de zgomot și pentru a găsi ACTUALIZARE declarație.
Steve Py

De asemenea, puteți posta tabelul de designer de ieșire pentru masa ta? Nu-masa au o reală PK set cu cele 4 coloane?
Steve Py

Am adăugat la răspunsul de mai sus pentru a include măsuri pentru a dublu-a verifica șirul de conexiune precum și de a verifica în date dacă sunt dublate de valori-cheie.
Steve Py

Am incercat solutia ta. primul lucru pe care-l uiți cum ți-e dor unele '=' în mașini var. al doilea lucru - atunci cand incerc sa fac update: masini.ActualReturnDate = acctualDate1; am primit o eroare cs1061.
elirans

În alte limbi

Această pagină este în alte limbi

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