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