我嘗試使用相同的值 (carNumber) 更新表后收到此錯誤,我的條件是更新實際回傳日期欄位為空的位置。
出于某種原因,查詢回傳 2 行,但實際上只有 1 行。我正在使用EF。這是函式:
錯誤 - 列印螢屏
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();
嘗試 db.saveChanges() 時出現錯誤
資料庫中的表,車號是 1000 - 列印螢屏
模型構建器.物體圖片
請讓我知道我該如何解決這個問題。
uj5u.com熱心網友回復:
通過向 car_rental_fields 表中添加一個新列(包含 Identity 的 id 列)來解決問題。正如我從這里和從網上了解到的,復雜的 pk 存在一個問題。在我的解決方案中,id 不是主鍵,但它使 linq 更新正確列的邏輯。感謝所有參與此問題的人。
uj5u.com熱心網友回復:
當 EF 無法為您的物體決議 PK 時,會發生此錯誤。在大多數情況下,對于簡單物體,EF 約定可以計算出 PK,但在您的情況下,您使用的是復合鍵,因此需要對其進行配置。根據您映射物體的方式,您可以通過以下方式執行此操作:
- EDMX
- 在 DbContext.OnModelCreating
- 使用
EntityTypeConfiguration宣告 - 使用物體本身的屬性
由于我們不知道您的物體是如何配置的,您可以通過使用物體中的屬性方法作為測驗來驗證這是原因。如果您使用的是 EDMX,則會生成物體類,因此您需要將其替換為 EDMX 中的配置。(在那里無法真正幫助您,因為我不使用該死的東西:D)
你可能會有這樣的事情:
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...
}
您甚至可能[Key]在這些欄位之一上有一個屬性,例如 CarNumber。如果物體中映射了 PK,則問題在于它不夠具體,無法唯一標識該行。當 EF 去更新一個物體時,它正在檢查并期望只更新表中的一行。它發現不止一行會受到影響,所以它失敗了。
[Key]使用列順序附加 的屬性,以便將其識別為組合鍵。
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...
}
假設這 4 列保證是表上的唯一約束,EF 將在構建它的 UPDATE SQL 陳述句時僅更新一行時得到滿足。
再次注意,如果這有效并且您正在使用 EDMX,您將需要查看和修改您的 EDMX 映射以進行適當的更改,因為該物體類可能會重新生成,從而丟失您的額外屬性。(我相信從 EDMX 生成的物體類有一個注釋標題,警告您它是一個生成的類,因此這是一個需要注意的指標。)
更新:我在這方面的主要懷疑是該表實際上沒有定義匹配的 PK,要么運行不同的 PK 組合,要么考慮到這些欄位的性質,更可能沒有 PK。EF 可以對沒有定義 PK 的表進行操作,但它確實需要一個 Key 定義來確保記錄可以被唯一標識。當該鍵定義不夠獨特時,就會發生您看到的錯誤。(即,如果您正在更新汽車 1,并選擇具有以下內容的行:car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 問題是不止一行具有該組合在資料庫中。如果您正在檢查的資料庫沒有超過一個匹配的行,那么您的應用程式幾乎可以肯定指向與您正在檢查的資料庫不同的資料庫。
你可以做的事情來驗證這一點:
- 獲取運行時連接字串并查看它是否與您正在檢查的資料庫匹配:
在運行查詢之前,添加以下內容:
// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
- 查看您實際查詢的資料:
.
var cars = db.CarRentalFields.Where(carNum =>
(carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null)).ToList();
雖然此查詢可能只回傳 1 條記錄,但這不是問題的原因。您需要的是該記錄的 CarNumber、StartDate、ReturnDate 和 UserId:
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.
這些查詢為您要更新的汽車記錄選擇假定的 PK 值,然后搜索汽車以查找具有預期關鍵欄位的匹配記錄。我的錢將用于當頂部查詢回傳 1 條記錄時,底部查詢回傳兩行,這意味著雖然只有 1 條記錄具有 #null ActualReturnDate 值,但您的 Key 對于該表的內容不夠唯一。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/368405.html
標籤:C# sql-server 实体框架 林克
