2012-03-16 8 views
4

式ツリー(バッチ更新用)に基づいてUPDATEコマンドを生成しようとしています。このような発現のために式<Func<T, T>から動的UPDATEコマンドを生成する>

UPDATE Product 
SET ProductTypeId = 123, 
ProcessAttempts = ProcessAttempts + 1 

次のUPDATEコマンドを想定し

は、どのように私は、コマンドのSET部分を生成することができます

Expression<Func<Product, Product>> updateExpression = entity => 
    new Product() { 
     ProductTypeId = 123, 
     ProcessAttempts = entity.ProcessAttempts + 1 
    }; 

SET ProductTypeId = 123, 
ProcessAttempts = ProcessAttempts + 1 
+0

あなたは何を使用していますか? LINQ to SQL?エンティティへのLINQ?他に何か?または、あなた自身のORMでこれを実装する方法を尋ねていますか? – svick

+0

私はLINQ to Entitiesを使用しています。私は、メモリ内のすべてのエンティティを最初にロードする必要なしにダイレクトUPDATEを実行したい(エンティティの1000秒を更新することができます)。 –

答えて

2

これは非常に単純なアプローチですが、私はそれが十分に良い願っています:

private static string ConvertToSetCommand<T>(Expression<Func<T, T>> exp) 
{ 
    if (exp.Body.NodeType != ExpressionType.MemberInit) 
    { 
     throw new ArgumentException("The expression must have an object initializer.", "exp"); 
    } 

    var builder = new StringBuilder("SET ", 100); 
    exp = (Expression<Func<T, T>>) new OmitParametersVisitor().Visit(exp); 

    var memberInit = (MemberInitExpression) exp.Body; 
    foreach (var assignment in memberInit.Bindings) 
    { 
     builder.Append(assignment.ToString()); 
     builder.Append(", "); 
    } 
    builder.Length -= 2; // Remove the last comma 

    return builder.ToString(); 
} 

private class OmitParametersVisitor : ExpressionVisitor 
{ 
    protected override Expression VisitMember(MemberExpression node) 
    { 
     if (node.Expression != null && node.Expression.NodeType == ExpressionType.Parameter) 
     { 
      return Expression.Parameter(node.Type, node.Member.Name); 
     } 
     else 
     { 
      return base.VisitMember(node); 
     } 
    } 
} 
関連する問題