在MVC 4中,“关系无法更改,因为一个或多个外键属性是非空的”

10

在我点击保存(更新)表单后,出现了以下错误:

由于一个或多个外键属性是非空的,因此无法更改关系。当关系发生变化时,相关的外键属性将设置为 null 值。如果外键不支持 null 值,则必须定义一个新的关系,将外键属性分配给另一个非 null 值,或删除不相关的对象。

这是我的控制器(在 switch 中的“Save”情况导致问题):

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(UserModel userModel, string act = null, int idx = 0)
{
    using (var dbContext = new userDbEntities())
    {

        if (userModel.User == null)
        {
           userModel.User = new UsersTable();
        }
        var newUser = userModel.User.userID == 0;
        userModel.CustomTypes = dbContext.CustomTypes.ToList();

        switch (act)
        {
            case "addcustom":
                userModel.User.CustomerTables.Add(new CustomerTable
                {
                    CustomType = new CustomType(),
                    UsersTable = userModel.User
                });
                break;
             case "deletecustom":
                 userModel.User.CustomerTables.RemoveAt(idx);
                 break;
             case "save":
                 foreach (var customer in userModel.User.CustomerTables)
                 {
                    customer.CustomType = dbContext.CustomTypes.Find(customer.CustomType.Id_NewCustomerType);
                 }
                 var dbUser = dbContext.UsersTables.Find(userModel.User.userID);
                 dbUser.TimeZoneId = userModel.User.TimeZoneId;
                 foreach (var custom in userModel.User.CustomerTables)
                 {
                      if (custom.CustomerID == 0)
                                dbUser.CustomerTables.Add(custom);
                 }
                 foreach (var custom in dbUser.CustomerTables.ToList())
                 {
                       var modelCustom =
                                userModel.User.CustomerTables.FirstOrDefault(o => o.CustomerID == custom.CustomerID);
                       if (modelCustom != null) //update it
                       {
                           custom.CustomType =
                                    dbContext.CustomTypes.Find(modelCustom.CustomType.Id_NewCustomerType);
                       }


                       if (userModel.User.CustomerTables.All(o => o.CustomerID != custom.CustomerID))
                                dbUser.CustomerTables.Remove(custom);
                  }
                  dbContext.SaveChanges();
                  break;
        } // end switch statements
        return View("Edit", userModel);
    }
}

有什么想法是错的吗...


如果将dbUser.CustomerTables.Remove(custom)更改为dbContext.Entry(custom).State = EntityState.Deleted,可以解决问题,但是简单的Add(保存)无法工作。 - Daniel K Rudolf_mag
可能是重复的问题:由于一个或多个外键属性是非可空的,关系无法更改 - Chris Moschini
4个回答

14

4

有一种更简单的方法来解决这个问题。
实际上,这是因为你有一个一对多的关系。当你想删除1端时,你有两种情况;你可以选择级联删除,或者你可以选择不删除任何内容。
如果你选择第一选项,它将在你删除1端时删除所有的多边实体。 你可以在实体图中设置这个选项。你只需要选择关系并将"End1 OnDelete"属性设置为级联。


在C#/EntityFramework代码中是否有一个命令可以标记删除语句以避免级联执行? - Ulysses Alves

0
我曾经遇到过这个问题,后来发现我在将对象从集合中移除后标记为已修改,而不是删除它。
例如,如果您要删除子项,则不应调用 context.Entry(child).State = EntityState.Modified;
相反,除了从集合中移除子项之外,还可以尝试像这样的操作:context.DeleteObject(child)
  • 我没有精确的代码,因为我的经验是使用Dev Express XAF ObjectSpace,可以使用((EFObjectSpace)objectSpace).ObjectContext进行转换;

0

我遇到了这个问题,很难解释(所以请原谅这个比喻),好消息是解决方案非常简单。

假设我有一个具有一对多关系的记录,它还有一个关系。(“汽车”有许多“人”;“人”有许多“孩子”)。当从汽车中删除人时会出现错误。执行 db.Cars.Remove(person); 会导致一个无关的错误。为了解决这个问题,我执行了 db.Cars.Persons.RemoveRange(children); <--- 在此之后,我遇到了本问题中所述的错误。要解决这个问题,请从数据库中删除孩子的孩子(不是“父母”,而是数据库本身)db.Children.RemoveRange(childrenOfPeople);

这是使用实体框架正确的最干净的解决方案,而不是设置记录状态。希望能帮助到某些人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接