Coffeehouse Thread

13 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Need help to build Expression Tree

Back to Forum: Coffeehouse
  • User profile image
    somnath2107

    Hi Experts,

    My Name is Somnath .I am working ASP.net Project in which I am using Linq

    I am creating Dynamic Lamabada Expression using Expression tree

    I want to use DateTime.Parse method for both the side for Property as well as Constant.

    I tried following way but I am getting an error.

    MethodInfo methodDateTimeParse = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) });

    Expression ExprLeft = Expression.Call(Expression.Property(variable, oFC.Field), methodDateTimeParse);  //Getiing error at this line (

    Static method requires null instance, non-static method requires non-null instance.

    Parameter name: instance

    )

    Please provide help

     

    Thanks & Regards,

    Somnath 

  • User profile image
    myefforts2

    It looks like Expression.Property(...) is returning null. Are `variable` and `oFC.Field` correct?

  • User profile image
    Richard.Hein

    Expression.Call(Expression.Property(...) ...) is the problem - that overload expects an instance of a class that you can call DateTime.Parse on - so it expects a DateTime object ... but Parse is static.  So you are supposed to give it a null instance - that means use the Expression.Call overload that does not take an Expression representing the instance.  Try this (partially tested):

    MethodInfo methodDateTimeParse = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) });
    var variable = Expression.Parameter(typeof(string), "foo");    
    Expression ExprLeft = Expression.Call(methodDateTimeParse, variable);

  • User profile image
    Richard.Hein

    Here's a fully tested version:

    MethodInfo methodDateTimeParse = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) });
    var variable = Expression.Parameter(typeof(string), "foo");
    Expression exprLeft = Expression.Call(methodDateTimeParse, variable);
    Expression<Func<string, DateTime>> lambda = Expression.Lambda<Func<string, DateTime>> (exprLeft, variable);
    Func<string, DateTime> func = lambda.Compile();    
    DateTime dt = func("2012-04-25");
    Console.WriteLine(dt);

  • User profile image
    somnath2107

    Hi Richard,

    Thank you so much for your help.

    The code which you gave that works fine with Constant which comes at the right side of the operator.

    I have List<Report> lstReport=New List<Report>();

    I want to write lstReport=lstReport.Where(o=>DateTime.Parse(o.Field)==DateTime.Parse(o.FieldValue));

    I am creating above statement dynamically

    like this 

      var variable = Expression.Variable(typeof(Report));

    foreach (SQWFilterConstraint oFC in oFilter.LstFilterConstraint) //usingthis collection I am making dynamic query
    {

      Expression  ExprLeft =Expression.Property(variable, oFC.Field);

    MethodInfo methodDateTimeParse = typeof(DateTime).GetMethod("Parse", newType[] { typeof(string) });

    var methodParam = Expression.Parameter(typeof(string), oFC.FieldValue);

    Expression exprRight = Expression.Call(methodDateTimeParse, methodParam );

    }

    var props = new[] { variable };

    var lambda = Expression.Lambda<Func<Report, bool>>(ExprPrev, props).Compile();

    ReportList = ReportList.Where(lambda).ToList();

    So Need to apply DateTime.Parse method on filed also which comes at the left side of the operator

    I will be very thank full if you provide help.

    Thanks in Advance 


  • User profile image
    Richard.Hein

    @somnath2107:

    This is the best I can do for you right now:

     

    MethodInfo methodDateTimeParse = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) });
    var variable = Expression.Parameter(typeof(string), "foo");
    Expression exprLeft = Expression.Call(methodDateTimeParse, variable);
    ConstantExpression exprRight = Expression.Constant(DateTime.Parse("2012-01-01"));
    BinaryExpression comparison = Expression.Equal(exprLeft, exprRight);
    Expression<Func<string, bool>> lambda = Expression.Lambda<Func<string, bool>> (comparison, variable);
    ConstantExpression constant = Expression.Constant (DateTime.Parse("2012-01-01"));
    Func<string, bool> func = lambda.Compile();    
    bool datesUnEqual = func("2012-04-25");
    Console.WriteLine(datesUnEqual);
    bool datesEqual = func("2012-01-01");
    Console.WriteLine(datesEqual);
     

  • User profile image
    somnath2107

    var variable = Expression.Parameter(typeof(string), "foo");

    I cant use like this because value "foo" should be taken from collection  at the runtime

     Expression  ExprLeft =Expression.Property(variable, oFC.Field);

    Can we apply DateTime.Parse to above expression ?


  • User profile image
    Richard.Hein

    , somnath2107 wrote

    var variable = Expression.Parameter(typeof(string), "foo");

    I cant use like this because value "foo" should be taken from collection  at the runtime

     Expression  ExprLeft =Expression.Property(variable, oFC.Field);

    Can we apply DateTime.Parse to above expression ?


    Sorry I am swamped in the middle of a death march.  I suggest you ask the rest of your questions on Stackoverflow.com,  as you're bound to get more/better answers.

    Good luck,

    Richard

  • User profile image
    JoshRoss

    Am I the only one here that thinks this method of solving this problem is overkill? If you want to dynamically restrict a list of things, why not pass the list to some restriction function, based on whatever heuristics are available to you at runtime?

    -Josh

  • User profile image
    JoshRoss

    Am I the only one here that thinks this method of solving this problem is overkill? If you want to dynamically restrict a list of things, why not pass the list to some restriction function, based on whatever heuristics are available to you at runtime?

    -Josh

  • User profile image
    vesuvius

    , JoshRoss wrote

    Am I the only one here that thinks this method of solving this problem is overkill? If you want to dynamically restrict a list of things, why not pass the list to some restriction function, based on whatever heuristics are available to you at runtime?

    -Josh

    Overkill is the only way some people can think to solve a problem, especially if the code is non-readable to everybody except to themselves of course. It usually is an ego thing to make them think they are smart. I'm not saying this is the case here, but it usually is.

  • User profile image
    Richard.Hein

    How is it overkill? It's not a lot of code. And it will be similar nearly everytime. Expression trees are the way to create dynamic LINQ ... it's core to LINQ ... so how can you do it any easier, such that it can be serialized into an expression tree across whatever provider you are targeting?

  • User profile image
    JoshRoss

    @Richard.Hein: I could understand using dynamic LINQ, if you wanted to create a LINQ provider. But in most cases, people just want to pass around IEnumerables. Sometimes it's hard to tell the forest from the trees.

    -Josh

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.