Questo errore si verifica quando EF non è possibile risolvere il PK per la propria entità. Nella maggior parte dei casi per una semplice entità, EF convenzioni possono lavorare fuori il PK, ma nel tuo caso si utilizza una chiave composta quindi questo deve essere configurato. A seconda di come si mappatura delle entità che si può fare questo in:
- un EDMX
- in DbContext.OnModelCreating
- utilizzando un
EntityTypeConfiguration
dichiarazione
- l'utilizzo di attributi all'interno dell'ente stesso
Dal momento che non sappiamo come entità sono configurati, si può verificare come la causa utilizzando l'attributo approccio all'interno della vostra entità come un test. Se si utilizza un EDMX le classi di entità verrà generato in modo che si vuole sostituire con configurazione EDMX. (Non si può davvero aiutarti perché non uso il dang cose :D )
Probabilmente qualcosa di simile a:
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...
}
Si può anche avere un [Key]
attributo su uno di questi campi, come CarNumber. Se c'è un PK mappati nell'entità il problema è che non è abbastanza specifico per identificare univocamente la riga. Quando EF va ad aggiornare entità, è il controllo di, e in attesa di aggiornare solo una riga nella tabella. Si tratta di trovare più di una riga sarà influenzato in modo non riesce.
Aggiungere gli attributi per il [Key]
con l'ordine delle colonne in modo che è riconosciuta come una chiave composta.
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...
}
Fornite queste 4 colonne sono garantiti per essere un vincolo univoco sul tavolo, EF sarà soddisfatto solo quando una riga viene aggiornata quando si costruisce l'istruzione SQL UPDATE.
Notare ancora una volta che se questo funziona e si utilizza un EDMX, sarà necessario rivedere e modificare il vostro EDMX mappatura di apportare le opportune modifiche dal momento che la classe di entità potrebbero essere rigenerati, di perdere i vostri attributi extra. (Credo generato classi di entità da un EDMX avere un commento di intestazione avvertenza che si tratta di una classe generata, in modo che è un indicatore di guardare fuori per.)
Aggiornamento:
Il mio primo sospetto in questo sarebbe che il tavolo, in realtà, non hanno un corrispondente PK definito, in un diverso PK combinazione, o più probabilmente no PK, data la natura di tali campi. EF può operato tabelle che non PK definito, ma richiede una Chiave di definizione che garantisce registrazioni possono essere identificati in modo univoco. L'errore che si sta vedendo succede quando la chiave definizione non è abbastanza unico. (I. e. se si sta aggiornando auto 1, e la selezione di una riga:
car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 Il problema è che più di una riga è questa combinazione nel DB. Se il DB si sta verificando che non hanno più una sola riga corrispondente, l'applicazione è quasi certamente punta a un database diverso da quello che si sta verificando.
Cose che si possono fare per verificare questa:
- ottenere il runtime stringa di connessione e vedere se corrisponde il DB che si sta verificando:
Prima di eseguire la query, aggiungere il seguente:
// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
- Guarda i dati che si sta effettivamente eseguendo la query:
.
var cars = db.CarRentalFields.Where(carNum =>
(carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null)).ToList();
Mentre questa query restituisce solo 1 record, che non è la causa del problema. Quello che vuoi è il CarNumber, Datainizio, ReturnDate, e UserId per questo record:
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.
Queste query selezionare l'assunto PK valori per le auto dei record che si intende per aggiornamento, la ricerca di automobili per i record corrispondenti con le attese di campi Chiave. Il mio denaro sarebbe che mentre il top query restituisce 1 record, il fondo query restituisce due righe, il significato, mentre solo 1 record è un #null ActualReturnDate valore, la tua Chiave non è abbastanza unico per il contenuto di questa tabella.