【问题标题】:EF 6 error occurred while updating the object context更新对象上下文时发生 EF 6 错误
【发布时间】:2016-07-14 15:58:49
【问题描述】:

我有实体

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;

我尝试将导航属性设置为 null

user.Role = null;

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

user.Role = role;

但我总是出错

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

我正在使用的保存日期

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

【问题讨论】:

  • 我认为 BaseEntity 有一个带有属性 [Key] 的属性“Id”?
  • 不,属性“Id”没有属性[Key]
  • 这个一对多关系角色有 n 个用户吗?

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


【解决方案1】:

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

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

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

通过检查状态并仅在状态为“分离”时才添加该错误很容易修复。我认识到问题可能是保持上下文太久的症状,但所有这些都在一个 Web 表单中。

【讨论】:

  • 这为我修好了!我不小心将对象添加到上下文中两次。
  • 你帮了我@ChrisGheen!其他插入时应检查是否重复代码!
【解决方案2】:

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

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

假设您有一个User,其中有一个代表它的角色的ICollection<Roles>。你有一个Role,它有一个指向用户的User 属性。因此,如果您尝试更新UserRole 列表而不更新适当角色内的User,则会引发违反参照完整性约束的错误。

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

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?

【讨论】:

  • 在实体角色中我没有 ICollection。以及我在更新中的写作方式。有时我可以更新日期
  • 我只是作为一个例子。在您的情况下,它可能是您不小心忘记与User 一起更新的任何其他导航属性。
  • 我的意思是:确保同时更新 both UserRole。如果要更改 UserRole,则应更改 RoleUsers 集合。
【解决方案3】:

我找到了解决方法。

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

但这对性能来说是个坏主意

【讨论】:

    猜你喜欢
    • 2020-01-27
    • 1970-01-01
    • 2011-08-05
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    相关资源
    最近更新 更多