EF 6 error occurred while updating the object context

c# entity-framework entity-framework-6

Question

I have Entity

public class User : BaseEntity, IEntity
{
    public string UserName { get; set; }

    public string Avatar { get; set; }

    [IgnoreMap]
    public string Password { get; set; }

    public int RoleId { get; set; }

    public virtual Role Role { get; set; }

    public string RoleName { get; set; }

    public int RangId { get; set; }

    public string RangName { get; set; }

    public string Email { get; set; }

    public string LastName { get; set; }

    public string FirstName { get; set; }

    public string SurName { get; set; }

    public DateTime? Birthday { get; set; }

    public int Gender { get; set; }

    public int? CountryId { get; set; }

    public virtual Country Country { get; set; }

    public int? CityId { get; set; }

    public virtual City City { get; set; }

    public string Skype { get; set; }

    public string WebSite { get; set; }

    public string Interest { get; set; }

    public string Signature { get; set; }

    public DateTime DateRegistered { get; set; }

    public string IpAddress { get; set; }

    public string PasswordChange { get; set; }

    public Guid? ActivateKey { get; set; }

    public DateTime? DatePasswordChange { get; set; }

    public int TotalPost { get; set; }

    public string NewEmail { get; set; }

I try update role of user

var user = this._userRepository.GetEntity(userId);
user.RoleId = role.Id;

I try set navigation property to null

user.Role = null;

I try set navigation property to new role

user.Role = role;

But I always get error

Additional information: 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: A referential integrity constraint violation occurred: The property value(s) of 'Role.Id' on one end of a relationship do not match the property value(s) of 'User.RoleId' on the other end.

For save date I'm using

this._context.Entry(entity).State = EntityState.Modified;

UPDATE:

I found interesting fact. Sometimes I can change user role, and sometimes I can't. Examples

When user activation his account, I can change user role.

When user change email, I can't change user role.

I using code almost the same

Update

Code for activation user work fine

    public bool ActivateUser(Guid key)
    {
        var user = this._userRepository.GetEntity(item => item.ActivateKey == key);
        var role = this._roleRepository.GetEntity(item => item.RoleType == RoleType.User);

        if (user != null)
        {
            user.ActivateKey = null;
            user.RoleId = role.Id;
            this._userRepository.UpdateEntity(user);
            this._userRepository.SaveChanges();

            return true;
        }

        return false;
    }

Code for edit email user, I get error

A referential integrity constraint violation occurred: The property value(s) of 'Role.Id' on one end of a relationship do not match the property value(s) of 'User.RoleId' on the other end.

    public void UpdateEmail(int userId, string newEmail, string browserAgent, string ip)
    {
        var user = this._userRepository.GetEntity(item => item.Id == userId);
        var role = this._roleRepository.GetEntity(item => item.RoleType == RoleType.NoActivation);
        var activateKey = Guid.NewGuid();

        var editEmailNotification = new EditEmailNotification
        {
            UserName = string.IsNullOrEmpty(user.FirstName) ? user.UserName : user.FirstName,
            OldEmail = user.Email,
            NewEmail = newEmail,
            Ip = ip,
            WebBrowseAgent = browserAgent,
            ActivateKey = activateKey
        };

        user.NewEmail = newEmail;
        user.ActivateKey = activateKey;
        user.RoleId = role.Id;
        this._userRepository.UpdateEntity(user);
        this._userRepository.SaveChanges();

        this.SendNotificationLetterChangedAccountEmail(editEmailNotification);
    }
1
0
7/16/2016 12:56:19 AM

Accepted Answer

I found how fix this.

I updated my method update date. I added call method this._context.ChangeTracker.DetectChanges();

    public void UpdateEntity(T entity, bool isDetectChange = false)
    {
        if (isDetectChange)
        {

            this._context.ChangeTracker.DetectChanges();
        }

        this._context.Entry(entity).State = EntityState.Modified;
    }

We can call method all time or we can in context setting set

 this.Configuration.AutoDetectChangesEnabled = true;

But it's bad idea for performance

0
7/16/2016 4:40:25 PM

Popular Answer

I had the same problem, and spent 6 hours on it till I found the cause.

I was adding an entity to the context, and then saving. I was keeping the context, and keeping a reference to the entity. Later when the user pressed 'save' again then the error was caused by adding this same entity again to the same context. Prior to the first save, the state of the entity was 'Added', after first save it was 'Unchanged' - all as expected. When adding the entity the second time its state in the context was then 'Added' and this caused the error. I had assumed that by adding an existing entity to an existing context, it would keep the state as 'unchanged' (or modified if I modified the entity).

It seems that the database recognized the added entity as being the same as an existing unchanged one, and so the changes were all saved, but the object context was confused with two states of the same entity, and threw the exception

The bug was fixed easily by checking the state and only adding if the state is 'detached'. I recognize that the problem may be a symptom of keeping the context for too long, but all this is in one web form.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow