Каждое свойство объекта должно быть включено в обновление

У меня есть сущность "Реп"...

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.

У вас есть два метода, которые вы можете попробовать

  1. Создайте модель представления только с теми свойствами, которые вы хотите обновить.

  2. Сохраните значения других свойств в скрытых полях, они не будут возвращены нулевые

Другие вопросы по тегам