2

我发布了这个问题,但是有一个大笑,我覆盖了我的实际问题,只是发布了代码,然后它被投票关闭。我认为这个问题非常令人担忧并且没有得到公平的震动,所以我再次发布它。

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

EntityFramework 更新部分模型

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

1 回答 1

2

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

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

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

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

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

我会:

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

控制器:

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

于 2013-01-03T13:18:20.430 回答