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

时间:2013-01-03 12:52:33

标签: c# entity-framework refactoring entity-framework-4.1

我发布了这个问题,但有一个狂笑,我覆盖了我的实际问题 并刚刚发布代码,然后它被投票结束。我想出了这个问题 非常喜欢,并没有得到公平的震动,所以我再次发布它。

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

EntityFramework update partial model

我已将其修改为下面的代码,这样我就不必手动指定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);
    }

1 个答案:

答案 0 :(得分:2)

我不会依赖于传递给Edit操作的内容来了解​​可以更新的内容以及出于安全原因无法更新的内容(请记住,客户端可以更改发布到服务器的内容)。

public class YourEntity
{
    public long ID { get; set; }

    // Updatable fields
    public string Field1 { get; set; }
    ....
}

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

@model YourEntity
...
@Html.HiddenFor(model => model.ID)
...
@Html.EditorFor(model => model.Field1)

我会:

  1. 检查用户是否有权更新实体
  2. 使用其ID
  3. 从数据库中检索实际实体
  4. 按属性手动更新属性
  5. 保存到DB
  6. 控制器:

    [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多个字段,那么写起来很无聊,但至少你可以完全控制可以更新的属性和不能更新的属性。

相关问题