10

在我的模型中,我有一堆域对象。现在我在尝试更新用户对象时遇到问题。User 与 Role 对象有外键关系。当我在不更改外键值(FkRoleId)的情况下更新用户对象时,一切正常。但是,当我更改要更新的当前用户的角色时,出现错误:

发生参照完整性约束冲突:定义参照约束的属性值在关系中的主体对象和从属对象之间不一致。

这是我更新用户对象的方法:

public void Update(User user)
{
    using (var context = new DBEntities())
    { 
    context.Entry(user).State = System.Data.EntityState.Modified;
    context.SaveChanges();
    }
}

如何在不出现此异常的情况下更新我的用户对象?必须有一种方法可以将外键值更改为将用户映射到另一个角色。

在这种情况下,这是我的域类:

public partial class User
{
public User()
{
    this.Advertisers = new HashSet<Advertiser>();
    this.Cases = new HashSet<Case>();
    this.Materials = new HashSet<Material>();
}

public int PkId { get; set; }
public int FkRoleId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public System.DateTime Created { get; set; }
public bool Active { get; set; }

public virtual ICollection<Advertiser> Advertisers { get; set; }
public virtual ICollection<Case> Cases { get; set; }
public virtual ICollection<Material> Materials { get; set; }
public virtual Role Role { get; set; }
}


public partial class Role
{
public Role()
{
    this.Users = new HashSet<User>();
}

public int PkId { get; set; }
public string Name { get; set; }
public string Description { get; set; }

public virtual ICollection<User> Users { get; set; }
}
4

2 回答 2

29

引用您的评论:

然而; 如果我将导航属性 user.Role 设置为 null 它工作得很好。但是,这是推荐的工作方式吗?

是的,在这种情况下是这样。

您必须记住,您输入一个带有分离对象的新上下文user(包括对 的引用user.Role)。通过将状态设置为Modified您将对象user与与user.Role此新上下文相关的对象一起附加。

因为您正在使用外键关联 - 这意味着外键由FkRoleId模型类中的属性表示 - 关系以两种方式描述:通过导航属性user.Role和标量属性user.FkRoleId。如果这些不一致 - 即user.Role.PkId != user.FkRoleId- EF 不知道哪一个描述了正确的关系并抛出您所拥有的异常。

如果设置user.RolenullEF,则将 only 视为user.FkRoleId描述用户和角色之间关系的属性,并删除导致异常的歧义。

于 2013-03-14T21:36:37.730 回答
0

为了搜索者的利益,我遇到了同样的错误,但找到了一个快速修复。

我正在将具有 FK 关系的类加载到要编辑的视图中。即使没有任何更改,FK 也会被删除并发生此错误。修复是在包含 FK 的 Razor 视图中包含一个隐藏字段。例如

@Html.HiddenFor(model => model.ReleaseInfo.BookId)

复制下面的代码,以便您检查您的情况是否相似。

控制器动作

public ActionResult Edit(int id = 0)
        {
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            ViewBag.Id = new SelectList(db.ReleaseInfo, "BookId", "BookId", book.Id);
            return View(book);
        }

        //
        // POST: /Book/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Book book)
        {
            if (ModelState.IsValid)
            {
                db.Entry(book).State = EntityState.Modified;

                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.Id = new SelectList(db.ReleaseInfo, "BookId", "BookId", book.Id);
            return View(book);
        }

关系

图书.cs

  public class Book
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        [MaxLength(100)]
        public string Title { get; set; }


        public virtual ICollection<Author> Authors { get; set; }


        public virtual ReleaseInfo ReleaseInfo { get; set; }


        public virtual ICollection<ReRelease> ReReleases { get; set; }

    }

发布信息.cs

public class ReleaseInfo
    {
        // One to one relationship uses Books Key as Key.
        [Key, ForeignKey("Book")]
        public int BookId { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime ReleaseDate { get; set; }


        public virtual Book Book { get; set; }
    }
于 2015-09-10T14:33:35.707 回答