2011-02-13 77 views
1

我想創建一個方法,該方法可以取得我可能會更新的屬性並將其不感興趣的屬性保留下來。爲實體框架4.0中的表更新字段的一般解決方案

這裏是我做過什麼:

public static void updateTable(int id, string field1, string field2, string field3){ 
    using(var context = new Entities()){ 
     var obj = context.Table.Where(x=>x.id == id).FirstOrDefault(); 
     if(obj != null){ 
      obj.field1 = field1; 
      ... 

      obj.SaveChanges(); 
     } 
    } 
} 

但在這種模式中,我需要在所有4個參數傳遞給方法,即使我只是想更新只有一個字段。有沒有任何通用的解決方案,只更新我傳入的字段?

我想出了這樣的事情:

public static void updateTable(int id, object data_json){ 
    using(var context = new Entities()){ 
     var obj = context.Table.Where(x=>x.id == id).FirstOrDefault(); 
     if(obj != null){ 
      if(data_json['field1']!=null) //something like this 
       obj.field1 = data_json['field1']; 
      ... 

      obj.SaveChanges(); 
     } 
    } 
} 

但這不能處理我也想設置一個字段爲空的情況。還是有更好的解決方案?

回答

0

如果你不關心更新關係,您可以使用ApplyCurrentValues,只更新性能。

E.g:

public static void updateTable(int id, object data_json){ 
    using(var context = new Entities()) { 
     var obj = context.Table.Where(x=>x.id == id).FirstOrDefault(); 
     context.ApplyCurrentValues("Table", data_json); 
    } 
} 

它假定使用相同的密鑰的實體已經連接在圖中。在這種情況下,對var obj的查詢將確保該對象位於圖中,則其內容將被提供的對象上的標量屬性覆蓋。

您可能需要在data_json上進行明確的轉換以確保它與實體集中包含的類型相同。

+0

當我試過這個,只設置了3個可能的標量屬性中的1個,'ApplyCurrentValues`設置了其他2個屬性爲null。有什麼方法讓`ApplyCurrentValues`只更新我設置的值,而不改變屬性? – 2011-02-14 04:22:48

0

使用ExpandoObject將允許您僅發送要設置的屬性,並允許您指定null值。

例如:

public static void updateTable(int id, dynamic data){ 
    using(var context = new Entities()){ 
     var obj = context.Table.Where(x=>x.id == id).FirstOrDefault(); 
     if(obj != null){ 
      if (((IDictionary<string, object>)data).ContainsKey("field1")) 
       obj.field1 = data.field1; 
      ... 

      obj.SaveChanges(); 
     } 
    } 
} 

,你可以這樣調用它:

dynamic data = new ExpandoObject(); 

data.field1 = 123; 
data.field2 = null; 
data.field5 = "abc"; 

MyClass.updateTable(1, data); 
0

一切都可以與反思的時刻來解決。此功能解決了這個問題:

public void UpdateTable(int id, object values) 
    { 
     using (var entities = new MyEntities()) 
     { 
      var valuesType = values.GetType(); 
      var element = entities.MyTable.Where(t => t.ID == id).First(); 

      //We are iterating through all properties of updated element and checking 
      //if there is value provided for there properties in values parameter 
      foreach (var property in element.GetType().GetProperties()) 
      { 
       var valuesProperty = valuesType.GetProperty(property.Name); 
       //If values contain this property 
       if (valuesProperty != null) 
       { 
        //taking value out of values parameter 
        var value = valuesProperty.GetValue(values, null); 
        //setting it in our element to update 
        property.SetValue(element, value, null); 
       } 
      } 

      entities.SaveChanges(); 
     } 
    } 

用法:

UpdateTable(125, new { FieldA = 1, FieldB = "ABCD" }); 

你甚至可以使這種方法通過增加仿製表類型參數更加普遍。