UpdateModel MVC ведет себя странно и возвращает значения. Почему?

#c# #asp.net-mvc #entity-framework #updatemodel

#c# #asp.net-mvc #entity-framework #updatemodel

Вопрос:

У меня есть объект, который я пытаюсь обновить с помощью MVC (2), также используя EntityFramework framework.

Я знаю, что не предоставил много кода, но на самом деле не считаю это необходимым. Причина, по которой у меня такая логика, я объясню:

  • У меня есть несколько каскадных выпадающих списков, и когда один из выпадающих списков пуст, я использую jQuery, чтобы заполнить его «НЕИЗВЕСТНЫМ» значением, например, с идентификатором, подобным -1.
  • Итак, когда я получаю значение -1, я создаю НЕИЗВЕСТНОЕ значение, которое находится в другой таблице.
  • Затем я нахожу этот объект и присваиваю его Fruit

Код, подобный этому:

 if (id == -1)
            {
                //The object was unknown so create it
                var newUnknown = new Fruit
                                 {
Name = "UNKNOWN";
};

EntityFramework.AddToFruits(newUnknown);
EntityFramework.SaveChanges();
defaultValueObject = EntityFramework.Fruits.Single(x=>x.FruitID == newUnknown.FruitID);

object.Fruit = defaultValueObject;
object.Date = DateTime.Now;

UpdateModel(object);
EntityFramework.SaveChanges();
  

После выполнения UpdateModel(object); строки значение, которое я ввел, например, Fruit возвращается к тому, что было отправлено из формы … (которое равно -1), а затем EntityFramework.SaveChanges(); завершается ошибкой FK contrainst (потому что fruit с идентификатором -1 не существует)! Достаточно справедливо — но это не то, что я вам назначил!

Я не понимаю, почему он возвращается, потому что после первого AddToFruits() неизвестного в базе данных все в порядке… и все это до тех пор, пока UpdateModel(object); оно не будет в object

Если он добавит его так, как я ему назначил, исключения FK contraint не будет. Но UpdateModel в MVC решает сделать что-то странное и по умолчанию использует (возможно, то, что пришло с отправкой формы) и все портит.

Почему это происходит? Как я могу это исправить?

Ответ №1:

UpdateModel не делает ничего странного, она делает то, что должна делать; обновляет объект значениями из формы отправки.

EF отслеживает изменения, поэтому он пытается обновить значения базы данных с тем, что объект имеет на момент сохранения.

Решите это, внеся изменения после запуска UpdateModel.

Комментарии:

1. На самом деле вы имеете в виду «Решить это, внеся изменения после запуска UpdateModel » и ПЕРЕД вызовом EntityFramework.SaveChanges()

2. Да, это то, что я имел в виду. Вы также можете использовать метод белого списка, упомянутый ниже, но в этом случае вам все равно придется вручную связывать данные вместе.

Ответ №2:

Вы можете передать массив строк в UpdateModel, чтобы сообщить ему, какие свойства следует обновить в вашей модели.

 public class Fruit
{
    int ID { get; set; }
    bool IsTasty { get; set; }
    string MyOtherPropert { get; set; }
    DateTime Date { get; set; }
}

...

if (id == -1)
{
    //The object was unknown so create it
    var newUnknown = new Fruit
    {
        Name = "UNKNOWN"
    };
    EntityFramework.AddToFruits (newUnknown);
    EntityFramework.SaveChanges ();

    defaultValueObject = EntityFramework.Fruits.Single (x=>x.FruitID == newUnknown.FruitID);
    defaultValueObject.Date = DateTime.Now;

    UpdateModel (object, new string[] { "IsTasty", "MyOtherProperty" });

    EntityFramework.SaveChanges ();
}
  

Выполнение этого гарантирует, что все свойства, которые вы хотите обновить, будут обновлены, а те, которые вы хотите оставить в покое, не будут затронуты. В этом случае UpdateModel будет игнорировать идентификатор и дату.

Комментарии:

1. Это сработало, я действительно не понимаю, почему я должен вручную указывать, какие поля обновлять? По умолчанию UpdateModel(object) я бы предположил попытки обновить все, что изменилось? Никто конкретно не ответил, но, похоже, это переопределяет то, что было установлено в коде, и вместо этого берет это из формы. Другой ответ на этот вопрос предполагает, что я должен сделать это после UpdateModel вызова. Кажется странной практикой, и к тому же при этом вызове генерируется исключение, поэтому было бы странно писать для этого обработку исключения, а затем вручную обновлять ее после — как странно!

2. Он обновляет все поля, когда вы не указываете, а не только те, которые были изменены. Это включает в себя свойства, которые вы установили для него ранее перед вызовом UpdateModel . Итак, чтобы избежать этого, вы точно указываете MVC, какие свойства вы хотите обновить, чтобы он не переопределял те, которые вы хотите, чтобы он оставил в покое.