#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, какие свойства вы хотите обновить, чтобы он не переопределял те, которые вы хотите, чтобы он оставил в покое.