Microsoft。EntityFrameworkCore.DbUpdateConcurrencyException:'数据库操作的预期影响1行(s),但实际上影响到2行(s)

0

的问题

我收到这个错误一次我尝试更新表有相同的价值(carNumber),我的条件是,以更新其中的实际重返日期的领域是空。

由于某些原因,它看起来像查询返回2行,但实际上只有一个。 我使用的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();

错误提高当试图数据库。saveChanges()

表从数据库,汽车数量是1000印屏幕

模型构建器。实体pic

请让我知道我如何能解决这个问题。

c# entity-framework linq sql-server
2021-11-23 20:34:34
2
0

问题解决了通过增加一个新列car_rental_fields表,身份列包括身份。 我的理解,从这里,从该网页有一个问题复杂pk。 在我的解决方案的id不是一个主要关键,但它是使的逻辑皇宫更新正确的列。 谢谢'为所有人参与在这一问题。

2021-11-26 20:37:27
0

这一错误发生时EF无法解决的PK你的实体。 在大多数情况下,简单的实体,EF公约可以作出的PK,但在你的情况下,您使用的是一种复合的关键因此,这需要进行配置。 取决于你如何射你的实体,你可以做到这一点无论是:

  • EDMX
  • 在代码的第.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会满足的时候,只有一个行更新时,它建立的是更新SQL发言。

再次注意,如果这个工作和使用EDMX,你会需要审查和修改EDMX映射进行适当的修改,因为这类实体可以再生,失去了你的额外的属性。 (我相信所产生的实体类EDMX有一个评头警告你,这是一个产生类,因此这是一个指标来看。)

更新: 我的主要嫌疑犯,这将是表实际上并没有匹配的PK定义,无论是在运行一个不同的PK组合,或者更可能没有PK给性质的那些领域。 EF可以操作上表中没有PK定义,但是它需要一种关键定义,以确保记录可以唯一标识。 错误你都看到发生时,关键的定义不是唯一的不够的。 (I.e。 如果你正在更新车的1,而选择了一行,具有: car_number=1,start_day=2021-11-21,return_day=2021-11-22、user_id=0的问题是,多个行具有这种组合的数据库。 如果数据库检查没有多个匹配的行那么你的应用,是几乎可以肯定指向一个不同的数据库比你检查。

事情可以做,以验证这一点:

  1. 获得运行连串看看如果匹配数据库检查:

在你之前的运行查询,添加以下内容:

// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
  1. 看看你的数据是实际上查询:

.

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记录具有一个#空ActualReturnDate值,你的钥匙不是唯一的足够的内容,这表。

2021-11-26 22:57:48

我使用的下拉,你有没有看到我的打印屏幕模型的建设者?
elirans

是的,好,就是用代码的第s OnModelCreating模型构建器,所以关键是被定义。 接下来要检查是否列匹配PK/w独特的约束,在你的对应数据库。 如果不是,是钥匙可能需要扩大。 复合的钥匙应该尽量避免,因为他们使设置的关系,更多的工作。 你也可以使用的分析器来捕获的拟议更新的发言,然后将其转换成一个简单的选择看到什么行返回。 由于某些原因多于一个行回来。
Steve Py

另一件事是检查是否在运行时的应用被击中同一数据库为什么你们是检查。 你的数据是检查可能出现的唯一不够的,如果该数据库不是强制执行的一个独特的制约那些列,但是该数据库指出,在运行时具有重复行。
Steve Py

同样的错误发生,用你的解决方案,我需要改变我的功能吗? @史蒂夫Py
elirans

捕获SQL正在生成和运行的数据库。 我通常使用探查对于这一点,因此,对于SQL服务器和短程,在工具\SQL分析器。 运行,对数据库,然后再执行你的查询。 你可以使用一个断点在你的申请之前SaveChanges,然后明确的探查出之前恢复到清除以前的噪声和找到更新的发言。
Steve Py

还有,你可以发布该表的设计输出你的桌子吗? 没有一个实际PK集与那些4列?
Steve Py

我加入到回答上述步骤包括仔细检查的连接串以及验证的数据是否存在重复的关键价值观。
Steve Py

我试过你的解决方案。 第一件事它看起来就像你错过了一些'='在车var. 第二件事-当我试着让更新:汽车。ActualReturnDate=acctualDate1;我得到了一个错误cs1061.
elirans

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................