开发者

General solution to updating fields for table in Entity Framework 4.0

开发者 https://www.devze.com 2023-02-10 01:51 出处:网络
I want to create a method which can takes the properties I possibly may update and leaving those not interested untouched.

I want to create a method which can takes the properties I possibly may update and leaving those not interested untouched.

Here is what I did:

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

But in this pattern, I need to pass all 4 parameters into the method even I just want to update only one field. Is there any generic solution 开发者_StackOverflow中文版to update only the fields I passed in?

I came up something like this:

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

But this can't handle the case that I do want to set a field to be null. Or is there any better solution?


If you don't care about updating relationships, you can use ApplyCurrentValues, which only updates the scalar properties.

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

It assumes an entity with the same key is already attached in the graph. In this case, the query for var obj will ensure the object is in the graph, then it's contents are overridden with the scalar properties on the supplied object.

You might need an explicit cast on data_json to ensure it is of the same type contained in the entity set.


Using an ExpandoObject would allow you to send in only the properties you want to set, and would allow you to specify null values as well.

For example:

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

and you could call it like this:

dynamic data = new ExpandoObject();

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

MyClass.updateTable(1, data);


Everything can be solved with a moment of reflection. This function solves the problem:

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

Usage:

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

You can even make this method more universal by adding generic table type parameter.

0

精彩评论

暂无评论...
验证码 换一张
取 消