2012-03-16 28 views
4

我試圖根據表達式樹(用於批量更新)生成UPDATE命令。從表達式生成動態更新命令<Func<T, T>>

假設下面的UPDATE命令:

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

對於像這樣的表達式:

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

如何可以生成該命令的SET部分?

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

你在使用? LINQ to SQL? LINQ to Entities?還有別的嗎?還是你問如何在你自己的ORM中實現這個? – svick 2012-03-16 15:59:37

+0

我正在使用LINQ to Entities。我想執行一個直接的UPDATE,而不必首先加載內存中的所有實體(可以更新1000個實體)。 – 2012-03-16 16:03:47

回答

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); 
     } 
    } 
} 
相關問題