InvalidOperationException при редактировании SaveChange ASP.NET MVC

Вот мой код для действия HTTPPost Edit:

[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 как

Операция завершилась неудачно: связь не может быть изменена, так как одно или несколько свойств внешнего ключа не могут принимать значения NULL. Когда в отношения вносятся изменения, для связанного свойства внешнего ключа устанавливается нулевое значение. Если внешний ключ не поддерживает нулевые значения, необходимо определить новую связь, свойству внешнего ключа должно быть присвоено другое значение, отличное от нулевого, или должен быть удален несвязанный объект.

Я немного поискал, похоже, я должен изменить

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

to

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

Однако DelectObject для меня не вариант. Пожалуйста, помогите, спасибо.


comment
Почему вам нужно удалить, а затем добавить новый avatar (в отличие от простого обновления свойства FileName существующего)?   -  person    schedule 13.09.2015


Ответы (1)


Я думаю, что причина этой ошибки может быть скрыта в этой логике:

            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 имеет несколько элементов FilePath (более одного). В этом коде вы удаляете из таблицы 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 };

надеюсь я правильно понял вашу мысль

person Dmitry Bogomolov    schedule 13.09.2015