我将使用github.com/loresoft/EntityFramework.Extended库进行批量更新。以下是用于批量更新的示例代码:
context
.Tasks
.Where(t => t.StatusId == 1)
.Update(t => new Task { StatusId = 2 })
我想指定用户指定的 StatusId 或其他属性,如 Discontinued、UnitsInStock。
我如何通过将属性作为字符串传递并构建动态表达式来实现这一点。
我将使用github.com/loresoft/EntityFramework.Extended库进行批量更新。以下是用于批量更新的示例代码:
context
.Tasks
.Where(t => t.StatusId == 1)
.Update(t => new Task { StatusId = 2 })
我想指定用户指定的 StatusId 或其他属性,如 Discontinued、UnitsInStock。
我如何通过将属性作为字符串传递并构建动态表达式来实现这一点。
只要更新的是静态值(即不引用其他变量),您可以使用以下方法:
public static Expression<Func<T,T>> CreateNewObjectExpression<T>(Dictionary<string, object> props) {
// set props
var type = typeof(T);
// This is the `new T` part of the expression
var newExpr = Expression.New(type);
// Convert the values to set to expressions
var members = from prop in props
let val = Expression.Constant(prop.Value)
select new KeyValuePair<string, Expression>(prop.Key, val);
// this is the full new T { prop1 = val1 ... }
var initExpr = BindMembers(newExpr, members);
// And now we add the parameter part `t => `
return Expression.Lambda<Func<T, T>>(initExpr, Expression.Parameter(typeof(T)));
}
static MemberInitExpression BindMembers(NewExpression expr, IEnumerable<KeyValuePair<string, Expression>> assignments) {
Type type = expr.Type;
List<MemberBinding> bindings = new List<MemberBinding>();
foreach (var pair in assignments) {
MethodInfo info = type.GetProperty(pair.Key).GetSetMethod();
MemberBinding binding = Expression.Bind(info, pair.Value);
bindings.Add(binding);
}
return Expression.MemberInit(expr, bindings);
}
这些方法可以像这样使用:
var props = new Dictionary<string,object>();
// get the properties from the user instead, of course
props["StatusId"] = 2;
// Now get the expression:
var updateExpr = CreateNewObjectExpression<Task>(props);
// and apply it
context.Tasks.Where(t => t.StatusId == 1)
.Update(updateExpr);
请注意仅设置目标类中存在且可写的属性,否则会崩溃。