怎样才能指示实体框架不更新模型的属性

本文关键字:更新 模型 属性 框架 实体 指示 | 更新日期: 2023-09-27 18:11:06

我正在使用Asp.net MVC和实体框架(下面的代码只是为了演示)

我有一个像下面这样的模型

  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" />
}
h2控制器

    [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对象在控制器内接收有默认的时间值,并且实体框架也试图更新该字段。

我的问题是如何指示实体框架不更新属性。假设在上述情况下,如果为CreatedOn属性我说实体框架不更新它,我不会得到错误。

我在CreatedOn上尝试了[Editable(false)]属性,但它不起作用。

有一些选项,如,在更新之前,我首先从数据库加载现有的实体和复制createdOn属性.....

我想让你知道,在我的真实模型有很多属性,我不想更新,有很多这样的模型,所以我期待一些现实的答案。

编辑1

我先用代码

怎样才能指示实体框架不更新模型的属性

您得到的特定错误是因为CreatedOn被设置为默认值。当您进行回发时,您必须从数据库加载对象,更新它,然后保存它。通过这样做,你将停止这个特定的错误,你正在经历。

看起来您正在使用实体模型作为控制器中的模型。我不推荐这样做。通过专门为文章创建一个模型,您可以从模型中删除任何不可编辑的字段。然后将模型值从ViewModel复制到实体模型。这可以防止用户编辑您可能不希望他们编辑的属性。

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

这是一个好主意的主要原因是有人可能会尝试猜测哪些值也可能有效。例如,如果您在Person对象上有一个名为IsAdministrator的属性,而我要拦截该帖子并添加&IsAdministrator=on&Adminstrator=on&Admin=on(以覆盖几个基础),那么ModelBinder将获取该值并将其应用于模型。现在我刚成为你们系统的管理员。我意识到这是很多工作,如果你有很多模型,但它从来都不是一个好主意,使用你的实体模型的帖子。

您还可以使用Bind属性来限制映射器绑定的项。

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

这将防止绑定器绑定特定的属性。然而,它不会解决您的问题,因为当创建person对象时,总是设置默认值。解决这个问题的唯一方法是从数据库中加载对象,然后更新/保存它。

相关文章: