对象上下文 使用 时出错.EF 6 中的添加范围

本文关键字:添加 范围 EF 上下文 使用 出错 对象 | 更新日期: 2023-09-27 18:35:01

我正在尝试就使用 .EF 6 中的添加范围。我收到以下错误。

The changes to the database were committed successfully, but an error occurred while updating the object context. 
The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because 
the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are 
unique before calling AcceptChanges.

正如错误所述,我的记录实际上被添加到表中,所以我不知道在哪里修复错误。

做一些研究,我发现了一堆帖子,其他人说它与.edmx文件和表上的主键有关。他们的建议基本上是添加PK,然后重建.edmx文件。这不符合我的方案,原因有两个,一是我首先将 EF 6 与数据库一起使用,因此没有 .edmx 文件,二是它映射到 Oracle 11 DB,因此标识是使用触发器创建的(当我查看添加的记录时似乎有效(。

这是我正在使用的代码以及实体的类。

using (APIcontext db = new APIcontext())
            {
                if (listLostTime.Count > 0)
                {
                    db.GROUND_HOURS.AddRange(listLostTime);
                    db.SaveChanges();
                }
            }

和实体类

[Table("GROUND_HOURS")]
    public partial class GROUND_HOURS
    {
        [Key]
        public decimal RID { get; set; }
        [Required]
        [StringLength(8)]
        public string EMP_ID { get; set; }
        [StringLength(2)]
        public string COMPANY_CODE { get; set; }
        public DateTime OCCURRENCE_DATE { get; set; }
        [Required]
        [StringLength(25)]
        public string PAY_CODE { get; set; }
        public decimal PAY_HOURS { get; set; }
        public DateTime INSERT_DATE { get; set; }
    }

我正在寻找任何建议。

对象上下文 使用 时出错.EF 6 中的添加范围

使用属性修饰 RID 属性DatabaseGenerated( DatabaseGeneratedOption.Identity )

问题是实体框架在接受更改之前没有使用存储生成的值更新键值RID。 在您的情况下,创建多个GROUND_HOURS实体后,每个实体(大概(的默认RID值为 0。 当 EF 尝试接受更改时,它会识别多个具有相同键值的实体并发出警报。

感谢@Moho谁给出了最终的修复。这就是我更改实体类中的主键以使其工作的方式,也是我在应用程序中使用的方法。

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RID { get; set; }

我也能够以另一种方式修复它,只是为了让其他人知道。首先,因为这是和Oracle DB的RID(这是我的主键(被脚手架作为十进制。这导致当我将对象添加到列表而不专门为其分配值时,RID 始终为 0。为了解决这个问题,我将 RID 属性更改为可为空的 INT,然后在创建列表时设置 RID=NULL。

[Key]
public int? RID { get; set; }

这是我在创建列表时所做的。

foreach (var item in results)
{
GROUND_HOURS lostTime = new GROUND_HOURS();
lostTime.RID = null;
lostTime.EMP_ID = item.EmployeeId.ToString("D8");
lostTime.COMPANY_CODE = item.CompanyCode.Trim();
lostTime.OCCURRENCE_DATE = item.OccurrenceDate;
lostTime.PAY_CODE = item.PayCode.Trim();
lostTime.PAY_HOURS = item.Hours;
listLostTime.Add(lostTime);
}