asp.net-mvc 关系无法更改,因为一个或多个外键属性在 MVC 4 中不可为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23673182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:41:53  来源:igfitidea点击:

The relationship could not be changed because one or more of the foreign-key properties is non-nullable in MVC 4

asp.net-mvcentity-framework

提问by Daniel K Rudolf_mag

I am getting this error after click Save (update) my form:

单击保存(更新)我的表单后出现此错误:

The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

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

Here is my controller (case "Save" in swich couse problem):

这是我的控制器(swich couse 问题中的“保存”案例):

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

Any idea what is wrong...

知道出了什么问题......

回答by Mahmood Jenami

There is an easier way to solve this problem.
Actually this is because you have one to many relationship. When you want to delete 1 Side, you have two scenarios; You can choose cascade delete, or you can choose none.
If you select first option it will delete all the many side entities when you delete the 1 side. You can set this option in the Entity Diagram. You Only got to select the relationship and set "End1 OnDelete" property to Cascade.

有一种更简单的方法可以解决这个问题。
其实这是因为你有一对多的关系。当你想删除 1 Side 时,你有两种情况;您可以选择级联删除,也可以选择无。
如果您选择第一个选项,它会在您删除 1 边时删除所有多边实体。您可以在实体图中设置此选项。您只需选择关系并将“End1 OnDelete”属性设置为 Cascade。

回答by Kirsten Greed

I was experiencing this message, it turned out that I was marking the object as Modified after I had removed it from it's collection instead of deleting it.

我遇到了这条消息,结果是我将对象从它的集合中删除而不是删除后将其标记为已修改。

For example you don't want to call context.Entry(child).State = EntityState.Modified;
if in fact you are trying to delete the child.

例如你不想调用 context.Entry(child).State = EntityState.Modified;
如果实际上您正试图删除该孩子。

instead, as well as removing the child from the collection try something like context.DeleteObject(child)

相反,以及从集合中删除子项尝试类似 context.DeleteObject(child)

  • I haven't got the exact code because my experience was with Dev Express XAF ObjectSpace which can be cast to ObjectContext using ((EFObjectSpace)objectSpace).ObjectContext;
  • 我没有得到确切的代码,因为我的经验是使用 Dev Express XAF ObjectSpace,它可以使用 ((EFObjectSpace)objectSpace).ObjectContext; 转换为 ObjectContext;

回答by John Smith

I experienced this problem, it's complicated to explain (so please forgive the analogy), the good news is that the solution is very simple.

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

Assume I have a record with a one to many relationship, which also has a relationship. (A "Car" has a number of "People"; "People" have a number of "Children"). The error occurrs when removing people from car. Doing a db.Cars.Remove(person);. Caused an unrelated error. To resolve that issue I did a db.Cars.Persons.RemoveRange(children);<--- After this I experienced the error as stated in this question. To resolve this remove the child's children from the database (not the "Parent" but the database iteself) db.Children.RemoveRange(childrenOfPeople);.

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

This is the cleanest solution to the problem using entity framework correctly without setting the state of records. Hope that helps someone.

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