Reputation: 18084
I'm trying to generate an UPDATE command based on Expression trees (for a batch update).
Assuming the following UPDATE command:
UPDATE Product
SET ProductTypeId = 123,
ProcessAttempts = ProcessAttempts + 1
For an expression like this:
Expression<Func<Product, Product>> updateExpression = entity =>
new Product() {
ProductTypeId = 123,
ProcessAttempts = entity.ProcessAttempts + 1
};
How can I generate the SET part of the command?
SET ProductTypeId = 123,
ProcessAttempts = ProcessAttempts + 1
Upvotes: 4
Views: 964
Reputation: 6719
This is a very simplistic approach, but I hope it's good enough:
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);
}
}
}
Upvotes: 2