【问题标题】:Batch update specify column dynamically批量更新动态指定列
【发布时间】:2015-10-29 20:54:36
【问题描述】:

我将使用github.com/loresoft/EntityFramework.Extended 库进行批量更新。以下是用于批量更新的示例代码:

context
.Tasks
.Where(t => t.StatusId == 1)
.Update(t => new Task { StatusId = 2 }) 

我想指定用户指定的 StatusId 或其他属性,如 Discontinued、UnitsInStock。

如何通过将属性作为字符串传递并构建动态表达式来实现这一点。

【问题讨论】:

    标签: c# linq expression batch-updates


    【解决方案1】:

    只要更新的是静态值(即不引用其他变量),可以使用以下方法:

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

    注意只设置目标类中存在且可写的属性,否则会崩溃。

    【讨论】:

      猜你喜欢
      • 2017-10-26
      • 1970-01-01
      • 2022-06-23
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      相关资源
      最近更新 更多