2011-02-13 75 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" }); 

你甚至可以使这种方法通过增加仿制表类型参数更加普遍。