Táto chyba sa vyskytuje, keď EF nemôže vyriešiť PK pre vašu osobu. Vo väčšine prípadov pre jednoduché subjektov, EF dohovorov môžu pracovať v PK, ale vo vašom prípade používate kompozitný kľúč tak to musí byť nakonfigurované. V závislosti na tom, ako ste mapovanie vaše subjektov, môžete to urobiť buď v:
- je EDMX
- v DbContext.OnModelCreating
- pomocou
EntityTypeConfiguration
vyhlásenie
- pomocou atribútov v rámci účtovnej jednotky sám
Keďže nevieme, ako váš subjekty sú nakonfigurované, overiť si to môžete ako príčinu pomocou atribútu prístup do vášho subjektu ako test. Ak používate EDMX subjektu tried bude generovaný, takže si budete chcieť nahradiť to s konfigurácia v EDMX. (Nie naozaj pomôcť tam, pretože som nepoužívajte dang veci :D )
Budete pravdepodobne mať niečo ako:
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...
}
Môžete mať aj [Key]
atribút na jednej z týchto oblastí, ako CarNumber. Ak je PK mapované v účtovnej jednotke, problém je, že to nie je dostatočne konkrétne, aby sa jednoznačne identifikovať riadok. Keď EF ide o aktualizáciu jedného subjektu, je kontrola, a očakávanie, že aktualizácia len jeden riadok v tabuľke. Je to nájsť viac ako jeden riadok bude ovplyvnený tak to nepodarí.
Pridať atribúty na [Key]
s stĺpca, aby tak nie je uznaný ako zložený kľúč.
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...
}
Za predpokladu, že tieto 4 stĺpce sú zaručene jedinečný fixačný bod na stôl, EF budú spokojní, keď iba jeden riadok, sa aktualizujú, keď sa stavia, je to AKTUALIZÁCIU SQL vyhlásenie.
Poznámka znova, že ak to funguje a používate EDMX, budete musieť preskúmať a upraviť svoj EDMX mapovanie urobiť príslušné zmeny, pretože tento subjekt triedy by mohli byť obnovované, stráca svoje ďalšie atribúty. (Verím, že generované jednotka tried z EDMX máte komentár hlavičky s upozornením, že to je generovaný triedy, tak, že je indikátor pozor.)
Aktualizácia:
Moje hlavné podozrenie, že v tomto by sa, že v tabuľke nie je skutočne zodpovedajúce PK definované, či už beží iný PK kombinácia, alebo pravdepodobnejšie č PK vzhľadom na povahu týchto oblastiach. EF môže prevádzkovať na tabuľkách, ktoré nemajú PK definované, ale to vyžaduje Kľúč definícia, ktorá zabezpečuje záznamy môžu byť jednoznačne identifikované. Chybu ste videli, že sa stane, keď tlačidlo definícia nie je dosť jedinečný. (I. e. ak aktualizujete auto 1, a vyberiete riadok, ktorý má:
car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 problémom je, že viac než jeden riadok sa, že zmes v DB. Ak DB ste kontrola nemá viac ako jeden zodpovedajúci riadok, potom je vaša aplikácia, je takmer isté, že ukážete na inej databázy, ako sú kontrola.
Veci, ktoré môžete urobiť, aby ste si overili:
- získať runtime pripojenie reťazec a uvidíme, či to zodpovedá DB ste si vybrali:
Pred spustením váš dotaz, pridajte nasledujúce:
// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
- Pozrite sa na údaje, ktoré ste sa vlastne zisťuje:
.
var cars = db.CarRentalFields.Where(carNum =>
(carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null)).ToList();
Zatiaľ čo tento dotaz môže vrátiť len 1 záznam, ktorý nie je príčinou problému. To, čo chcete, je CarNumber, StartDate, ReturnDate, a UserId pre tento záznam:
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.
Tieto otázky vyberte predpokladá PK hodnoty pre auto záznam chcete povedať, že chcete aktualizovať, a potom hľadať autá na zodpovedajúce záznamy s očakávané Kľúčové oblasti. Moje peniaze by na ktoré zatiaľ čo top dotaz vráti 1 záznam, spodný dotaz vráti dvoch radoch, čo znamená, zatiaľ čo iba 1 záznam má #null ActualReturnDate hodnotu, Kľúč nie je jedinečná dosť za obsah tejto tabuľky.