Каждое свойство объекта должно быть включено в обновление
У меня есть сущность "Реп"...
public partial class rep
{
public string repid { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
public string Department { get; set; }
many, many more properties...
}
Затем у меня есть форма, которая обновляет только имя и фамилию представителя. Когда форма отправляется, имя и фамилия обновляются, но для всех остальных свойств устанавливается значение NULL.
Я хочу, чтобы другие свойства были оставлены в покое, чтобы они сохраняли там существующие значения.
Я мог бы включить все свойства объекта со скрытыми полями формы для передачи их значений в метод Edit, но есть ли лучший / более простой способ?
Я знаком с настройкой свойства IsModified...
entry.Property(e => e.Title).IsModified = true;
Но это тоже кажется ненужным. Это путь или есть лучший путь?
3 ответа
Вы либо используете свойство IsModified, как вы упомянули, либо вы можете создать модель представления, имеющую свойства, которые вы хотите изменить, и использовать маппер, такой как AutoMapper, для копирования значений из входных данных в сущность. Обычно у меня есть базовый класс с моими изменяемыми данными и подкласс с отношениями и данными, которые я не хочу изменять, например, CreatedBy и тому подобное. Скрытые поля, безусловно, НЕ путь.
Код, который вы используете для визуализации представления и обновления сущности, довольно актуален, но отсутствует, но я могу догадаться, как они выглядят:
@model ...rep
@using (Html.BeginForm()) {
@Html.HiddenFor(m => m.repid )
@Html.TextBoxFor(m => m.FirstName )
@Html.TextBoxFor(m => m.LastName)
<input type="submit" />
}
И в вашем контроллере:
[HttpPost]
public ActionResult Update(rep model)
{
using (var context = new MyContext())
{
context.reps.Attach(model);
context.SaveChanges();
}
return RTA(...);
}
Это присоединение сущности, которая была опубликована, которая является совершенно новым объектом, неизвестным контексту и его трекеру изменений. Прикрепляя подобную сущность, вы сообщаете контексту, что это новое представление, которое вы хотите сохранить, т. Е. С большинством свойств, установленным в null
,
Вы можете легко исправить это, сначала извлекая сущность, а затем обновляя только необходимые свойства:
[HttpPost]
public ActionResult Update(rep model)
{
using (var context = new MyContext())
{
var entity = context.reps.Find(rep.repid);
entity.FirstName = model.FirstName;
entity.LastName = model.LastName;
context.SaveChanges();
}
return RTA(...);
}
Но не делай этого. Смотрите Что такое ViewModel в MVC? или ViewModel Best Practices или выполните поиск в Интернете или на этом сайте по "mvc viewmodel".
Главным образом, потому что ваша сущность базы данных содержит столбцы, которые вы не хотите отображать или обновлять ( массовое назначение), и потому, что рано или поздно вы захотите использовать в своем представлении дополнительные свойства (раскрывающиеся данные, переменные скрипта, связанные сущности), которые вы не можете прикрепить в вашей базе данных объектов.
В общем, вы можете сказать: не используйте модели сущностей для моделей представлений, особенно когда они публикуются. Итак, viewmodel - это путь:
public class RepresentativeViewModel
{
public string RepID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Затем вам нужно только изменить объявление модели вашего представления:
@model ...RepresentativeViewModel
И ваш контроллер выглядит как простое решение:
[HttpPost]
public ActionResult Update(RepresentativeViewModel model)
{
using (var context = new MyContext())
{
var entity = context.reps.Find(rep.RepID);
entity.FirstName = model.FirstName;
entity.LastName = model.LastName;
context.SaveChanges();
}
return RTA(...);
}
Вы можете, конечно, заменить entity.FirstName = model.FirstName;
отображение кода в какое-то автоматизированное решение, например, с использованием AutoMapper.
У вас есть два метода, которые вы можете попробовать
Создайте модель представления только с теми свойствами, которые вы хотите обновить.
Сохраните значения других свойств в скрытых полях, они не будут возвращены нулевые