C# 更新中是否需要包含实体的每个属性

C# 更新中是否需要包含实体的每个属性,c#,sql-server,asp.net-mvc,entity-framework,C#,Sql Server,Asp.net Mvc,Entity Framework,我有一个实体“代表” 然后我有一个表格,只更新代表的名字和姓氏。提交表单时,会更新名字和姓氏,但其他所有属性都设置为null 我希望其他属性不受影响,以便它们保留现有值 我可以使用隐藏的表单字段包含实体的所有属性,以便将它们的值传递给编辑方法,但是有更好/更简单的方法吗 我熟悉设置IsModified属性 entry.Property(e => e.Title).IsModified = true; 但这似乎也没有必要。这是一种方法,还是有更好的方法?您可以使用前面提到的IsModifi

我有一个实体“代表”

然后我有一个表格,只更新代表的名字和姓氏。提交表单时,会更新名字和姓氏,但其他所有属性都设置为null

我希望其他属性不受影响,以便它们保留现有值

我可以使用隐藏的表单字段包含实体的所有属性,以便将它们的值传递给编辑方法,但是有更好/更简单的方法吗

我熟悉设置IsModified属性

entry.Property(e => e.Title).IsModified = true;

但这似乎也没有必要。这是一种方法,还是有更好的方法?

您可以使用前面提到的IsModified属性,也可以创建具有要更改的属性的视图模型,并使用映射器(如AutoMapper)将值从输入复制到实体。通常,我有一个基类,它有我的可修改数据,还有一个子类,它有我不想更改的关系和数据,比如CreatedBy之类的东西。隐藏字段显然不是解决问题的方法。

您可以尝试两种方法

  • 创建仅包含要更新的特性的视图模型

  • 将其他属性的值存储在隐藏字段中,它们不会返回null


  • 用于呈现视图和更新实体的代码非常相关,但缺少,但我可以猜出它们是什么样子:

    @model ...rep
    
    @using (Html.BeginForm()) {
    
        @Html.HiddenFor(m => m.repid )
        @Html.TextBoxFor(m => m.FirstName )
        @Html.TextBoxFor(m => m.LastName)
    
        <input type="submit" />
    }
    
    这是附加已发布的实体,它是上下文及其更改跟踪器未知的全新对象。通过附加这样的实体,可以告诉上下文这是要保存的新表示形式,即大多数属性设置为
    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(...);
    }
    
    但是不要这样做。在“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。

    就我个人而言,这就是我映射到DTO或没有多余列的自定义ViewModel类的情况。你不能从db加载对象,更新属性,然后保存吗?这样就省去了其他一切。+1谢谢你的详细解释。这很有帮助。
    @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(...);
    }