C# 实体框架如何仅更新模型中的特定字段?

C# 实体框架如何仅更新模型中的特定字段?,c#,entity-framework,refactoring,entity-framework-4.1,C#,Entity Framework,Refactoring,Entity Framework 4.1,我贴出了这个问题,但有一种大笑,我把我的实际问题写得太多了 刚刚发布代码,然后投票决定关闭。我想到了这个问题 这本书的内容非常丰富,没有得到应有的重视,所以我再次发布它 我使用的是实体框架4.1。我有一个表单,上面有很多字段。表本身的字段实际上比表单上的字段多。我正试图找到一种方法来更新已经更改的字段。我在这里找到了一个例子: 我已经将其修改为下面的代码,这样我就不必手动指定40多个字段。我希望有一个比下面更干净的方法来做这件事。有吗 警告:下面的代码是初稿,相当粗糙。欢迎所有建议。谢谢

我贴出了这个问题,但有一种大笑,我把我的实际问题写得太多了 刚刚发布代码,然后投票决定关闭。我想到了这个问题 这本书的内容非常丰富,没有得到应有的重视,所以我再次发布它

我使用的是实体框架4.1。我有一个表单,上面有很多字段。表本身的字段实际上比表单上的字段多。我正试图找到一种方法来更新已经更改的字段。我在这里找到了一个例子:

我已经将其修改为下面的代码,这样我就不必手动指定40多个字段。我希望有一个比下面更干净的方法来做这件事。有吗

警告:下面的代码是初稿,相当粗糙。欢迎所有建议。谢谢

    [HttpPost]
    public ActionResult Edit(Location location, FormCollection fields)
    {
        if (ModelState.IsValid)
        {
            //db is my context
            db.Locations.Attach(location);

            StringBuilder sb = new StringBuilder();

            //Get properties of Location object
            PropertyInfo[] pi = typeof(Location).GetProperties();

            //loop over keys of fields submitted by the post
            foreach (string submittedField in fields.Keys)
            {
                //If a property name on the Location object matches a field name
                //of one of the submitted properties then mark the property as 
                //modified
                if (pi.Any(prop => prop.Name.Equals(submittedField)) && 
                    !"ID".Equals(submittedField) )
                {
                    db.Entry(location).Property(submittedField).IsModified = true;
                    sb.AppendLine(submittedField + "Value: " + db.Entry(location).Property(submittedField).CurrentValue );
                }
            }

            LogUtil.WriteCondensed(sb.ToString());

            //Save changes to the database
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(location);
    }

我不会依赖传递给您的
Edit
操作的内容来知道哪些内容可以更新,哪些内容出于安全原因不能更新(请记住,发布到服务器上的内容可以由客户端更改)

在视图中,使用隐藏字段作为要更新的对象的ID(razor语法):

我会:

  • 检查用户是否有权更新实体
  • 使用其ID从数据库检索实际实体
  • 按属性手动更新属性
  • 保存到数据库
  • 控制器:

    [HttpPost]
    public ActionResult Edit(YourEntity model)
    {
        try
        {
            yourServiceLayer.Update(User.Identity.Name, model);
        }
        catch (CustomSecurityException)
        {
            ...
        }
    }
    
    服务:

    public class YourServiceLayer
    {
        public YourEntity Update(string userName, YourEntity entity)
        {
            // Check user has rights to edit the entity (if necessary)
            if (this.CanUpdate(userName, entity.ID))
            {
                // Gets actual entity from DB
                var yourDbEntity = this.GetByID(entity.ID);
    
                // Updates each property manually
                yourDbEntity.Field1 = entity.Field1;
                ....
    
                // Saves to DB
                this.Save(yourDbEntity);
                return yourDbEntity;
            }
            else
            {
                // Security exception
                throw new CustomSecurityException(...);
            }   
        }
    
        public bool CanUpdate(string userName, long entityID)
        {
            // Insert logic here
            return ....;
        }
    
        ...
    }
    

    如果您有40多个字段,那么是的,写起来很无聊,但至少您可以完全控制可以更新的属性和不能更新的属性。

    我真的不想表现得懒惰,但如果我在视图模型中添加自定义数据注释,以指示在编辑过程中应该保存哪些字段,这看起来可行吗?不过,我仍然需要对所有位置属性使用反射来获得注释,不是吗?
    [HttpPost]
    public ActionResult Edit(YourEntity model)
    {
        try
        {
            yourServiceLayer.Update(User.Identity.Name, model);
        }
        catch (CustomSecurityException)
        {
            ...
        }
    }
    
    public class YourServiceLayer
    {
        public YourEntity Update(string userName, YourEntity entity)
        {
            // Check user has rights to edit the entity (if necessary)
            if (this.CanUpdate(userName, entity.ID))
            {
                // Gets actual entity from DB
                var yourDbEntity = this.GetByID(entity.ID);
    
                // Updates each property manually
                yourDbEntity.Field1 = entity.Field1;
                ....
    
                // Saves to DB
                this.Save(yourDbEntity);
                return yourDbEntity;
            }
            else
            {
                // Security exception
                throw new CustomSecurityException(...);
            }   
        }
    
        public bool CanUpdate(string userName, long entityID)
        {
            // Insert logic here
            return ....;
        }
    
        ...
    }