在Entity Framework 4.0中更新表的字段的一般解决方案

时间:2011-02-13 21:34:11

标签: entity-framework-4

我想创建一个方法,它可以获取我可能更新的属性,并保留那些不感兴趣的属性。

这是我做的:

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();
        }
    }
}

但这无法处理我想将字段设置为null的情况。或者有更好的解决方案吗?

3 个答案:

答案 0 :(得分: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上进行显式强制转换,以确保它与实体集中包含的类型相同。

答案 1 :(得分: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);

答案 2 :(得分: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" });

您甚至可以通过添加通用表类型参数来使此方法更具通用性。