对象上下文 使用 时出错.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; }
}
我正在寻找任何建议。
使用属性修饰 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);
}