问题
Let's say the user modifies his profile record that contains fields such as FirstName, LastName, Email, etc.
For each field that is modified, the change is stored as a key-value pair in a list of type:
List<Tuple<string, object>>
The key in this key-value pair represents the actual table column.
While trying to update the record, here is one way to do it:
foreach (Tuple<string, object> field in changeList) {
if (field.Item1.equals("FirstName")) {
user.FirstName = field.Item2;
}
if (field.Item1.equals("Email")) {
user.Email = field.Item2;
}
...
}
db.SaveChanges()
I am thinking there must be a better way to accomplish this.
I guess I could use reflection to set each property on the user
foreach(tuple<string, object> field in changeList) {
user.GetType().InvokeMember(field.Item1,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, user, field.Item2);
}
I am wondering if there is even better way. Perhaps I could build a "var" object dynamically that will also let me use TryUpdateModel() method.
回答1:
I have done something similar but using a custom object of type string and object. I also don't know if this is the efficient one but it gets the job done. To demonstrate I have used Tuple where first item1 is string and item2 is an object.
List<Tuple<string, object>> listTuple = new List<Tuple<string, object>>();
listTuple.Add(new Tuple<string, object>("FirstName", "Foo"));
listTuple.Add(new Tuple<string, object>("LastName", "Bar"));
PropertyInfo[] props = user.GetType().GetProperties();
foreach (var prop in props)
{
if (prop.PropertyType.Name == "ICollection`1")
{
//Do not do anything these are navigation properties in entity framework.
//For eg. If User has Applications then do not set values for Applications.
}
else
{
//Match each property with matching Item1 in Tuple.
var myTuple = listTuple.Where(x => x.Item1 == prop.Name).First();
//Set Users Property using myTuple's Item2 which is an object here.
prop.SetValue(user, myTuple.Item2, null);
}
}
回答2:
One way is to use the old pal ADO.NET.
The other way is Dynamic LINQ
Edit
Sorry, I Think Dynamic LINQ can only be used for filtering. May be ADO.NET is the best option. I'm out of ideas.
来源:https://stackoverflow.com/questions/19349285/entity-framework-how-to-update-fields-from-a-list-of-key-value-pairs