更新对象上下文时发生EF 6错误

时间:2016-07-14 15:58:50

标签: c# entity-framework entity-framework-6

我有实体

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; }

我尝试更新用户角色

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

我尝试将navigation属性设置为null

user.Role = null;

我尝试将导航属性设置为新角色

user.Role = role;

但我总是得到错误

  

其他信息:已成功提交对数据库的更改,但更新对象上下文时发生错误。 ObjectContext可能处于不一致状态。内部异常消息:发生了引用完整性约束违规:关系一端的“Role.Id”的属性值与另一端的“User.RoleId”的属性值不匹配。 / p>

对于保存日期我正在使用

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

更新

我发现了一个有趣的事实。有时我可以改变用户角色,有时候我不能。 实例

当用户激活他的帐户时,我可以更改用户角色。

当用户更改电子邮件时,我无法更改用户角色。

我使用的代码几乎相同

更新

激活用户工作正常的代码

    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;
    }

编辑电子邮件用户的代码,我收到错误

  

发生了参照完整性约束违规:属性   关系一端'Role.Id'的值与   另一端'User.RoleId'的属性值。

    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);
    }

3 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,花了6个小时才找到原因。

我在上下文中添加了一个实体,然后保存。我保留了上下文,并保留了对实体的引用。稍后当用户再次按下“保存”时,错误是由于将同一实体再次添加到同一上下文引起的。在第一次保存之前,实体的状态为“已添加”,在首次保存之后它是“未更改” - 全部按预期进行。当第二次添加实体时,其在上下文中的状态是“添加”,这导致错误。我假设通过将现有实体添加到现有上下文,它将使状态保持“未更改”(或者如果我修改实体则修改)。

似乎数据库将添加的实体识别为与现有的未更改实体相同,因此更改全部保存,但是对象上下文与同一实体的两个状态混淆,并抛出异常

通过检查状态可以轻松修复错误,只有在状态为“已分离”时才添加。我认识到问题可能是长时间保持上下文的一种症状,但所有这些都是一种网络形式。

答案 1 :(得分:1)

检查导航属性。很可能该错误意味着您正在从关系的一侧更新实体的导航属性,但不会从另一侧更新实体。

让我们快速浏览一下这个例子:

假设您有User,其ICollection<Roles>代表其角色。并且您有一个Role,其User属性引用用户。因此,如果您尝试更新User的{​​{1}}列表而不更新相应角色中的Role,则会引发参照完整性约束违规错误。

另外,请检查这些链接,它们可能会帮助您解决问题:

error occurred while updating the object context

Error:A referential integrity constraint violation occurred on db.SaveChanges() in .net?

How to update entity?

Why become referential constraints inconsistent after updating foreign key?

答案 2 :(得分:0)

我找到了解决这个问题的方法。

我更新了方法更新日期。我添加了调用方法 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;
    }

我们可以一直调用方法或者我们可以在上下文设置集

 this.Configuration.AutoDetectChangesEnabled = true;

但这对于表现来说是个坏主意