Asp.net mvc 4 EF 5,更新对象给出;发生引用完整性约束冲突";

Asp.net mvc 4 EF 5,更新对象给出;发生引用完整性约束冲突";,asp.net-mvc-4,entity-framework-5,Asp.net Mvc 4,Entity Framework 5,在我的模型中,我有一堆域对象。现在我在尝试更新用户对象时遇到问题。用户与角色对象具有foreignkey关系。当我更新用户对象而不更改foreignkey值(FkRoleId)时,一切正常。但是,当我更改要更新的当前用户的角色时,会出现以下错误: 发生引用完整性约束冲突:属性 定义引用约束的值不一致 在关系中的主体对象和从属对象之间 以下是我如何更新我的用户对象: public void Update(User user) { using (var context = new DBEnt

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

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

以下是我如何更新我的用户对象:

public void Update(User user)
{
    using (var context = new DBEntities())
    { 
    context.Entry(user).State = System.Data.EntityState.Modified;
    context.SaveChanges();
    }
}
如何更新用户对象而不出现此异常? 必须有一种方法可以将mappen用户的foreignkey值更改为另一个角色

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

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; }
}
公共部分类用户
{
公共用户()
{
this.advisors=newhashset();
this.Cases=newhashset();
this.Materials=new HashSet();
}
公共int PkId{get;set;}
public int FkRoleId{get;set;}
公共字符串名称{get;set;}
公共字符串电子邮件{get;set;}
公共字符串密码{get;set;}
public System.DateTime已创建{get;set;}
公共bool活动{get;set;}
公共虚拟ICollection{get;set;}
公共虚拟ICollection案例{get;set;}
公共虚拟ICollection材质{get;set;}
公共虚拟角色{get;set;}
}
公共部分类角色
{
公共角色()
{
this.Users=new HashSet();
}
公共int PkId{get;set;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
公共虚拟ICollection用户{get;set;}
}
引用您的评论:


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

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

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

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


如果您设置<代码>用户>角色>代码> null >代码> EF将考虑<代码>用户.FKROLIDID <代码> >作为描述用户和角色之间关系的属性和导致异常的歧义被删除。

< P>为了搜索者的利益,我得到了相同的错误,但发现了一个快速修复。

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

@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);
        }
关系

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

    }

然而;如果我将导航属性user.Role设置为null,它就可以正常工作。但是,这是推荐的工作方式吗?这可能是这些QA的副本,如果我需要附加一个具有更改的导航属性和完整的标量属性的对象,该怎么办?我能告诉EF使用导航属性作为“主要”吗?@Vasaka:不,你不能。
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; }
    }