как можно поручить entity framework не обновлять свойство модели

#c# #asp.net-mvc-3 #entity-framework #entity-framework-4 #entity-framework-4.1

#c# #asp.net-mvc-3 #entity-framework #entity-framework-4 #entity-framework-4.1

Вопрос:

Я использую Asp.net MVC и Entity framework (приведенный ниже код предназначен только для демонстрации)

У меня есть модель, подобная приведенной ниже

   public class Person
    {
        [Key]
        public int Id { get; set; }

        [Required]
        public string FirstName { get; set; }

        /*Time at which person was created*/
        public DateTime CreatedOn { get; set; }  /*should not change once created*/
    }
  

Во время создания вставки нового пользователя я вручную установил свойство CreatedOn datetime.

При обновлении

В моем представлении есть только одно текстовое поле

  @using (Html.BeginForm())
        {
            @Html.LabelFor(a => a.FirstName) 
            @Html.EditorFor(a => a.FirstName) 
            @Html.ValidationMessageFor(a => a.FirstName)            
            <br />
            <input type="submit" name="name" value="submit" />
}
  

Контроллер

     [HttpPost]
    public ActionResult EditPerson(Person person)
    {
        if (ModelState.IsValid)
        {
            db.Entry(person).State = EntityState.Modified;
            db.SaveChanges();

            /* ----------------
              Error here
              ----------------- 
             */

            return RedirectToAction("ListPerson");
        }
        return View(person);            
    }
  

Я получаю сообщение об ошибке в указанной точке моего кода, ошибка: The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. ошибка кажется очевидной, поскольку person объект, полученный внутри контроллера, имеет значение времени по умолчанию, и entity Framework также пытается обновить это поле.

Мой вопрос в том, как я могу поручить entity Framework не обновлять свойство. Предположим, что в приведенном выше случае, если для CreatedOn свойства я говорю entity framework не обновлять его, я не получу ошибку.

Я попробовал [Editable(false)] включить атрибут CreatedOn , но это не сработало.

Есть несколько вариантов, например, перед обновлением я сначала загружаю существующий объект из базы данных и копирую свойство CreatedOn…..

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

Редактировать 1

Сначала я использую код.

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

1. На данный момент не на моем компьютере, но делаю это из памяти. Я думаю, вы можете выбрать поле в своей модели сущности, а на вкладке «Свойства» выбрать «вычислено из сгенерированного в хранилище поля шаблона».

2. если я не ошибаюсь, то вычисленное значение будет меняться CreatedOn при каждом обновлении, также вы не увидите ошибку при попытке в памяти.

Ответ №1:

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

Похоже, что вы используете свою entity model в качестве модели в своем контроллере. Я бы не рекомендовал это. Создав модель специально для post, вы можете удалить все не редактируемые поля из своей модели. Затем вы скопировали бы значения модели из ViewModel в свою Entity model. Это не позволяет пользователям редактировать свойства, которые вы, возможно, не хотите, чтобы они редактировали.

 public class PersonViewModel
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string FirstName { get; set; }
}
  

Основная причина, по которой это хорошая идея, заключается в том, что кто-то может попытаться угадать, какие значения также могут работать. Например, если у вас было вызвано свойство вашего Person объекта IsAdministrator , и я должен был перехватить сообщение и добавить amp;IsAdministrator=onamp;Adminstrator=onamp;Admin=on (чтобы охватить несколько баз), тогда ModelBinder примет это значение и применит его к модели. Теперь я только что стал администратором в вашей системе. Я понимаю, что это большая работа, если у вас много моделей, но никогда не рекомендуется использовать ваши модели сущностей для сообщений.

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

 public ActionResult EditPerson([Bind(Exclude = "CreatedOn")] Person person)
  

Это должно помешать связующему связывать это конкретное свойство. Однако это не решит вашу проблему, поскольку при создании объекта person всегда устанавливается значение по умолчанию. Единственный способ исправить это — загрузить ваш объект из базы данных, а затем обновить / сохранить его.