Home

Interesting Expression mapping question

Hi,
I'm working on an LINQ expression mapper using ExpressionVisitor. The idea is to replace an expression's sourcetype by a different type with same properties and fields (and perhaps property- and fieldnames). When I us simple types (int, string) everything works fine. But when I try to access complex properties, mapping fails with an ArgumentException(Die Eigenschaft "System.String LogisticResourceStateName" ist für den Typ "LogisticResourceStateDest" nicht definiert. ).
Any ideas why the expression isn't mapped?

Regards

Oskar


public class LogisticResourceStateSource
{

public long LogisticResourceStateId { get; set; }
public string LogisticResourceStateName { get; set; }

public ICollection LogisticResources { get; set; }
}

public class LogisticResourceSource
{
public long LogisticResourceId { get; set; }
public string LogisticResourceName { get; set; }
public long LogisticResourceStateId { get; set; }
public long LogisticResourceTypeId { get; set; }

public LogisticResourceStateSource LogisticResourceState { get; set; }
public LogisticResourceTypeSource LogisticResourceType { get; set; }
}

public class LogisticResourceTypeSource
{

public long LogisticResourceId { get; set; }
public string LogisticResourceName { get; set; }

public ICollection LogisticResources { get; set; }
}

public class LogisticResourceStateDest
{

public long LogisticResourceStateId { get; set; }
public string LogisticResourceStateName { get; set; }

public ICollection LogisticResources { get; set; }
}

public class LogisticResourceDest
{
public long LogisticResourceId { get; set; }
public string LogisticResourceName { get; set; }
public long LogisticResourceStateId { get; set; }
public long LogisticResourceTypeId { get; set; }

public LogisticResourceStateDest LogisticResourceState { get; set; }
public LogisticResourceTypeDest LogisticResourceType { get; set; }
}

public class LogisticResourceTypeDest
{

public long LogisticResourceId { get; set; }
public string LogisticResourceName { get; set; }

public ICollection LogisticResources { get; set; }
}

void Main()
{
var expression = (Expression>)(lr => lr.LogisticResourceStateId > 1 && lr.LogisticResourceName.StartsWith("Vau") && lr.LogisticResourceState.LogisticResourceStateName.StartsWith("S"));
Expression> expressionConverted = expression.Convert( );
}

public static class ExpressionNodeExtensions
{
///
/// The convert.
///
///
/// The expression node.
///
///
/// The source type
///
///
/// The destination type
///
///
/// The result type
///
///
/// The .
///
public static Expression> Convert(this ExpressionNode expressionNode)
{
var expression = expressionNode.ToExpression();
var expressionConverter = new ExpressionConverter();
return (Expression>)expressionConverter.Convert(expression);
}

public static Expression> Convert(this Expression> expression)
{
var expressionConverter = new ExpressionConverter();
return (Expression>)expressionConverter.Convert(expression);
}

}



///
/// The expression converter.
///
///
/// The source type of parameter to convert from
///
///
/// The destination type of parameter to convert to
///
///
/// Used to specify the expected result type
///
internal class ExpressionConverter : System.Linq.Expressions.ExpressionVisitor
{
///
/// The replace parameter.
///
private ParameterExpression replaceParam;

///
/// The convert.
///
///
/// The expression.
///
///
/// The .
///
public Expression Convert(Expression expr)
{
return this.Visit(expr);
}

///
/// The visit lambda.
///
///
/// The node.
///
///
/// The Type of the expression node
///
///
/// The .
///
protected override Expression VisitLambda(Expression node)
{
if (typeof(T) != typeof(Func))
{
return base.VisitLambda(node);
}

this.replaceParam = Expression.Parameter(typeof(TDestination));
return Expression.Lambda>(this.Visit(node.Body), this.replaceParam);
}

///
/// The visit parameter.
///
///
/// The node.
///
///
/// The .
///
protected override Expression VisitParameter(ParameterExpression node)
{
return node.Type == typeof(TSource) ? this.replaceParam : base.VisitParameter(node);
}

///
/// The visit member.
///
/// /// The node. /// /// /// The . /// /// /// Thrown if data object has no corresponding member /// protected override Expression VisitMember(MemberExpression node) { if (node.Member.DeclaringType != typeof(TSource)) { return base.VisitMember(node); } var member = typeof(TDestination).GetMember(node.Member.Name, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).FirstOrDefault(); if (member == null) { throw new InvalidOperationException("Cannot identify corresponding member of DataObject"); } //return Expression.MakeMemberAccess(this.Visit(node.Expression), member); var expression = this.Visit(node.Expression); var result = Expression.MakeMemberAccess(expression, member); return result; } }
Sign In or Register to comment.