Я пытаюсь найти справочную информацию об ошибке, которую я получаю при использовании .AddRange в 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; }
    }

Ищу любые предложения.

1
Caverman 17 Фев 2016 в 21:07

2 ответа

Лучший ответ

Украсьте свойство RID атрибутом DatabaseGenerated( DatabaseGeneratedOption.Identity )

Проблема в том, что структура объекта не обновляет значение ключа RID с помощью значения, созданного хранилищем, до принятия изменений. В вашем случае, когда создано несколько сущностей GROUND_HOURS, каждая из них (предположительно) будет иметь значение по умолчанию RID, равное 0. Когда EF пытается принять изменения, он распознает, что несколько сущностей имеют одинаковое значение ключа. и жалуется.

2
Moho 17 Фев 2016 в 18:27

Спасибо @Moho, который дал окончательное исправление. Вот как я изменил первичный ключ в своем классе сущности, чтобы он работал, и это то, что я использовал в своем приложении.

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

Я также смог исправить это другим способом, просто чтобы сообщить другим. Во-первых, потому что это и Oracle DB, RID (который является моим первичным ключом) был шаблоном как десятичный. Это привело к тому, что RID всегда был равен 0, когда я добавлял свой объект в список без специального присвоения ему значения. Чтобы обойти это, я изменил свойство RID на значение INT, допускающее значение NULL, а затем, когда я создал свой список, я установил 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);
}
0
Caverman 17 Фев 2016 в 19:30