2013-01-03 88 views
2

我發佈了這個問題,但有一個笑話,我重寫了我的實際問題 ,只是發佈代碼,然後它被投票關閉。我想到了這個問題 是非常fubared,並沒有得到公平的動搖,所以我再次發佈它。實體框架如何更新模型中的特定字段?

我正在使用實體框架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); 
    } 

回答

2

我不會依靠什麼傳遞給你的Edit行動,知道什麼可以被更新,什麼不能出於安全原因(記住,什麼是發佈到服務器可以通過客戶端進行更改)。

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

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

在視圖中,使用隱藏字段的對象的ID來更新(剃刀語法):

  1. 檢查用戶具有權限:

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

    我會然後更新實體

  2. 使用其ID從012處檢索實際實體
  3. 手動更新本身地產
  4. TY保存到數據庫

控制器:

[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場,然後是它的無聊寫,但至少您可以完全控制可更新的屬性和不可以的屬性。

+0

+1不映射用戶輸入到反射屬性 –

+1

我真的沒有試圖懶惰,但如果我添加一個自定義數據註釋到我的視圖模型來表示在編輯期間應保存哪些字段,將這似乎可行?儘管如此,我仍然必須使用對所有Location屬性的反射來獲取註釋,但是,不是嗎? – jason