编辑SaveChange ASP.NET MVC时出现InvalidOperationException

时间:2015-09-13 06:29:58

标签: asp.net-mvc entity-framework asp.net-mvc-4 invalidoperationexception savechanges

以下是我的HTTPPost编辑操作代码:

[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult Edit(int? id, HttpPostedFileBase upload)
{

    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    var PeopleUpdateToDate = db.People.Find(id);
    if (TryUpdateModel(PeopleUpdateToDate, "", new string[] { "LastName", "FirstMidName", "Age", "Address", "Interests", "FilePath" }))
    { 
        if (upload != null && upload.ContentLength > 0)
        {
            if (PeopleUpdateToDate.FilePaths.Any(f => f.FileType == FileType.Avatar))
            {
                db.FilePaths.Remove(PeopleUpdateToDate.FilePaths.First(f => f.FileType == FileType.Avatar));
            }
            var avatar = new FilePath
            {
                FileName = System.IO.Path.GetFileName(upload.FileName),
                FileType = FileType.Avatar
            };                    

            PeopleUpdateToDate.FilePaths = new List<FilePath> { avatar };
        }                

        db.Entry(PeopleUpdateToDate).State = EntityState.Modified;
        db.SaveChanges();

        return RedirectToAction("Index");           

    }      
    return View(PeopleUpdateToDate);
}

我得到InvalidOperationException为

  

操作失败:无法更改关系,因为   一个或多个外键属性是不可为空的。当一个   改变了关系,相关的外键属性是   设置为空值。如果外键不支持空值,   必须定义新的关系,外键属性必须是   分配了另一个非空值,或者不相关的对象必须是   删除。

我做了一些搜索,看起来我应该改变

db.FilePaths.Remove(PeopleUpdateToDate.FilePaths.First(f => f.FileType == FileType.Avatar));

db.FilePaths.DeleteObject(PeopleUpdateToDate.FilePaths.First(f => f.FileType == FileType.Avatar));

但是,DelectObject不适合我。请帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

我认为这个错误的原因可能隐藏在那个逻辑中:

            if (PeopleUpdateToDate.FilePaths.Any(f => f.FileType == FileType.Avatar))
            {
                db.FilePaths.Remove(PeopleUpdateToDate.FilePaths.First(f => f.FileType 
                  == FileType.Avatar));
            }
            var avatar = new FilePath
            {
                FileName = System.IO.Path.GetFileName(upload.FileName),
                FileType = FileType.Avatar
            };                    

            PeopleUpdateToDate.FilePaths = new List<FilePath> { avatar };

因此,我们假设您的PeopleUpdateToDate对象有几个FilePaths项(不止一个)。在此代码中,您只从FiletPaths表中删除一个FilePath项

        if (PeopleUpdateToDate.FilePaths.Any(f => f.FileType == FileType.Avatar))
        {
            db.FilePaths.Remove(PeopleUpdateToDate.FilePaths.First(f => f.FileType == FileType.Avatar));
        }

但是你清除了PeopleUpdateToDate.FilePaths列表。因此,如果该列表中有多个FilePath项,那么除了已删除的项之外的所有项都将使用其外键PeopleId == null。

使用像这样的东西可能会更好

PeopleUpdateToDate.FilePaths.Add(avatar);

而不是

PeopleUpdateToDate.FilePaths = new List<FilePath> { avatar };

我希望我能理解你的想法