none
Linq Expression Conversion from one type to another RRS feed

  • Question

  • Hi,

    Am trying to convert the LINQ Expression from ViewModel to Model, wasn't successful. Any help would be appreciated.

    The below is from my controller where the user can dynamically do a select criteria on ViewModel and it has to be converted to different model.

    From:   Expression<Func<FacilityViewModel,bool>> filter = null)  and i have convert this

    To :  Expression>Func<Facility, bool>>  filter

    Any help is appreciated.

    Thanks

    Roopesh

      


    Roopesh

    Monday, July 14, 2014 8:47 PM

Answers

  • Hello,

    From your description, is it that you are under below scenario?

    Your filter would be same except the accepted type as:

    Expression<Func<Order, bool>> filterOrder = order => order.OrderID == 1;
    Expression<Func<OrderDetail, bool>> filterOrderDetail = order => order.OrderID == 1;

    And you want to filter the Order collection using the filterOrderDetail.

    If it is, expression trees are immutable, so to do this you would need to walk the entire tree, rebuilding it and substiting any uses of the type with the equivalent - usually by writing a "visitor". When encountering a MemberExpression or MethodCallExpression, you would check the member's declaring type - if it is the one you don't want, recreate it

    Note that you can't do this just at the places it is used; the entire tree must be regenerated. For example, you can follow this example:

    Create a class inherited from ExpressionVistor:

    class MyExpressionVisitor : ExpressionVisitor
    
            {
    
                public ParameterExpression NewParameterExp { get; private set; }
    
    
                public MyExpressionVisitor(ParameterExpression newParameterExp)
    
                {
    
                    NewParameterExp = newParameterExp;
    
                }
    
    
                protected override Expression VisitParameter(ParameterExpression node)
    
                {
    
                    return NewParameterExp;
    
                }
    
    
                protected override Expression VisitMember(MemberExpression node)
    
                {
    
                    if (node.Member.DeclaringType == typeof(OrderDetail))
    
                        return Expression.MakeMemberAccess(this.Visit(node.Expression),
    
                           typeof(Order).GetMember(node.Member.Name).FirstOrDefault());
    
                    return base.VisitMember(node);
    
                }
    
            }
    

    Write your query as:

    Expression<Func<OrderDetail, bool>> filterOrderDetail = od => od.OrderID == 1;
    
    
                    var visitor = new MyExpressionVisitor(Expression.Parameter(typeof(Order),
    
                            filterOrderDetail.Parameters[0].Name));
    
    
                    var exp2 = Expression.Lambda<Func<Order, bool>>
    
                                    (visitor.Visit(filterOrderDetail.Body), visitor.NewParameterExp);
    
    
    
                    var result = db.Orders.Where(exp2).ToList();
    

    If I misunderstand, please let me know.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.



    Tuesday, July 15, 2014 9:27 AM
    Moderator

All replies

  • Hello,

    From your description, is it that you are under below scenario?

    Your filter would be same except the accepted type as:

    Expression<Func<Order, bool>> filterOrder = order => order.OrderID == 1;
    Expression<Func<OrderDetail, bool>> filterOrderDetail = order => order.OrderID == 1;

    And you want to filter the Order collection using the filterOrderDetail.

    If it is, expression trees are immutable, so to do this you would need to walk the entire tree, rebuilding it and substiting any uses of the type with the equivalent - usually by writing a "visitor". When encountering a MemberExpression or MethodCallExpression, you would check the member's declaring type - if it is the one you don't want, recreate it

    Note that you can't do this just at the places it is used; the entire tree must be regenerated. For example, you can follow this example:

    Create a class inherited from ExpressionVistor:

    class MyExpressionVisitor : ExpressionVisitor
    
            {
    
                public ParameterExpression NewParameterExp { get; private set; }
    
    
                public MyExpressionVisitor(ParameterExpression newParameterExp)
    
                {
    
                    NewParameterExp = newParameterExp;
    
                }
    
    
                protected override Expression VisitParameter(ParameterExpression node)
    
                {
    
                    return NewParameterExp;
    
                }
    
    
                protected override Expression VisitMember(MemberExpression node)
    
                {
    
                    if (node.Member.DeclaringType == typeof(OrderDetail))
    
                        return Expression.MakeMemberAccess(this.Visit(node.Expression),
    
                           typeof(Order).GetMember(node.Member.Name).FirstOrDefault());
    
                    return base.VisitMember(node);
    
                }
    
            }
    

    Write your query as:

    Expression<Func<OrderDetail, bool>> filterOrderDetail = od => od.OrderID == 1;
    
    
                    var visitor = new MyExpressionVisitor(Expression.Parameter(typeof(Order),
    
                            filterOrderDetail.Parameters[0].Name));
    
    
                    var exp2 = Expression.Lambda<Func<Order, bool>>
    
                                    (visitor.Visit(filterOrderDetail.Body), visitor.NewParameterExp);
    
    
    
                    var result = db.Orders.Where(exp2).ToList();
    

    If I misunderstand, please let me know.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.



    Tuesday, July 15, 2014 9:27 AM
    Moderator
  • Thanks Fred. I followed the same pattern but little different way and it worked. Appreciate your help.

    Thanks

    Roopesh


    Roopesh

    Tuesday, July 15, 2014 10:06 PM