Ошибка Entity Framework: объект с нулевым значением EntityKey не может быть присоединен к контексту объекта - PullRequest
9 голосов
/ 14 декабря 2011

В моем приложении есть следующий код ...

    public Boolean SaveUserInformation(UserInfoDTO UserInformation)
    {
        return dataManager.SaveUserInfo(new UserInfo()
        {
            UserInfoID = UserInformation.UserInfoID.HasValue ? UserInformation.UserInfoID.Value : 0,
            UserID = UserInformation.UserID,
            ProxyUsername = UserInformation.ProxyUsername,
            Email = UserInformation.Email,
            Status = UserInformation.Status
        });
    }

Этот код вызывает метод для объекта dataManager, который использует Entity Framework ...

    public Boolean SaveUserInfo(UserInfo userInfo)
    {
        try
        {
            //Validate data prior to database update
            if (userInfo.UserID == null) { throw new Exception("UserInfoDomainModel object passed to PriorityOne.Data.DataManager.SaveUserInfo with UserID property set to NULL."); }
            if (userInfo.ProxyUsername == null) { throw new Exception("UserInfoDomainModel object passed to PriorityOne.Data.DataManager.SaveUserInfo with ProxyUsername property set to NULL."); }
            if (userInfo.Email == null) { throw new Exception("UserInfoDomainModel object passed to PriorityOne.Data.DataManager.SaveUserInfo with Email property set to NULL."); }

            if (userInfo.UserInfoID == 0)
            {
                //Perform Insert
                using (PriorityOneEntities entities = new PriorityOneEntities())
                {
                    entities.UserInfoes.AddObject(userInfo);
                    entities.SaveChanges();
                }
            }
            else
            {
                //Perform Update
                using (PriorityOneEntities entities = new PriorityOneEntities())
                {
                    entities.Attach(userInfo);
                    entities.SaveChanges();
                }
            }

            return true;
        }
        catch (Exception ex)
        {
            //TODO: Log Error
            return false;
        }

    }

Вставкапо этому коду работает просто отлично.Но когда я пытаюсь выполнить обновление, я получаю сообщение об ошибке: «Объект с нулевым значением EntityKey не может быть присоединен к контексту объекта».

Это происходит в этой строке кода: entity.Attach(userInfo);

То, что я пытаюсь сделать, - это избежать обхода базы данных, просто выбрать запись, в которую я позже внесу изменения и обновить, таким образом, совершив две поездки в базу данных.

Есть идеи, что не так или как мне лучше это сделать?

Спасибо.

Ответы [ 2 ]

20 голосов
/ 14 декабря 2011

Похоже, вы используете EF 4.1+
Вы должны сообщить EF, что вы хотите, чтобы ваша сущность была обновлена ​​(измененное состояние):

//Perform Update
using (PriorityOneEntities entities = new PriorityOneEntities())
{
    entities.Entry(userInfo).State = EntityState.Modified;
    entities.SaveChanges();
}

P.S. Вам не нужно явно звонить Attach. Это сделано под капотом.

Обновление :
основываясь на ваших комментариях, вы используете EF 4.0. Вот что вы должны сделать, чтобы прикрепить ваш объект, как изменено в EF 4.0:

 ctx.AddObject("userInfoes", userInfo);
 ctx.ObjectStateManager.ChangeObjectState(userInfo, EntityState.Modified);
 ctx.SaveChanges();  

Вы не можете использовать Attach метод. От http://msdn.microsoft.com/en-us/library/bb896271.aspx:

Если несколько сущностей определенного типа имеют одинаковое значение ключа, Entity Framework сгенерирует исключение. Чтобы избежать получения исключения, используйте метод AddObject , чтобы прикрепить отсоединенные объекты, а затем соответствующим образом изменить состояние.

3 голосов
/ 14 декабря 2011

С MSDN

Объект, который передается методу Attach, должен иметь действительный Значение EntityKey. Если у объекта нет действительного значения EntityKey, используйте метод AttachTo, чтобы указать имя набора сущностей.

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...