簡體   English   中英

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException:'數據庫操作預計會影響 1 行,但實際上會影響 2 行

[英]Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: 'Database operation expected to affect 1 row(s) but actually affected 2 row(s)

一旦我嘗試使用相同的值(carNumber)更新表,我就會收到此錯誤,我的條件是更新實際返回日期字段為 null 的位置。

出於某種原因,查詢返回 2 行,但實際上只有 1 行。 我正在使用EF。 這是 function:

錯誤 - 打印屏幕

   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() 時出現錯誤

db 中的表,車號為 1000 - 打印屏幕

modelBuilder.Entity 圖片

請讓我知道如何解決這個問題。

當 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 去更新一個實體時,它正在檢查並期望只更新表中的一行。 它發現不止一行會受到影響,因此它會失敗。

Append [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 映射以進行適當的更改,因為該實體 class 可能會重新生成,從而丟失您的額外屬性。 (我相信從 EDMX 生成的實體類有注釋 header 警告您它是生成的 class,因此這是一個需要注意的指標。)

通過向 car_rental_fields 表中添加一個新列來解決問題,id 列包含身份。 正如我從這里和 web 了解的那樣,復雜的 pk 存在問題。 在我的解決方案中,id 不是主鍵,但它使 linq 更新正確列的邏輯。 感謝所有參與此問題的人。

EF 像這樣生成 sql 查詢

update carfields SET  retdate = @retdate  WHERE 
car_number = @car_number and userId=@u.. 
and date1 = @date1 and date2=@date2

由於您具有包含日期的如此復雜(輕聲說)的主鍵,因此它可以輕松 select 2 行而不是 1 行。

恕我直言,為了防止將來出現此類問題,您應該考慮從 PK 中排除日期,或者最好只使用通用的自動增量鍵並在所有其他列上創建唯一索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM