RE: [re-motion-users] Prevent PartialEvaluatingExpressionTreeVisitor from evaluating certain expressions

28 views
Skip to first unread message

Gordon Watts

unread,
Dec 30, 2012, 3:11:02 PM12/30/12
to re-moti...@googlegroups.com
I did something like this. I apologize for not being near my code so I can't show you a code snippet. Basically you need to create a special expression class to represent these server variables. Second, you insert an expression parser early in the sequence that is triggered on a member variable access. In the member access method check to see if this is the server variable, and if it is, create and return the special expression object. This will prevent further parsing, but allow the rest of the relinq expression reduction machinery to function. You will, obviously, have to add some special detection code in your main query parser or expression visitor object to translate this to the proper server variable.

I'll try to post more when I am near my actual code again! Happy new year!

-----Original Message-----

From: Nathan Baulch
Sent: 26 Dec 2012 21:28:25 GMT
To: re-moti...@googlegroups.com
Subject: [re-motion-users] Prevent PartialEvaluatingExpressionTreeVisitor from evaluating certain expressions

My server provides special $-prefixed identifiers that clients can use in their queries. I'd like to make these identifiers available in LINQ queries via strongly typed static fields however PartialEvaluatingExpressionTreeVisitor keeps trying to evaluate them. What's the best way to bypass the evaluation of MemberExpression instances that point to my special fields?

    var results = new MyQueryable<Contact>()
        .Where(c =>
ServerVariable.Key != "0001" && ServerVariable.Updated < new DateTime(2012, 1, 1))
        .ToList();

   
public static class ServerVariable
    {
       
public static readonly ServerVariable<string> Key = new ServerVariable<string>("$key");
       
public static readonly ServerVariable<DateTime> Updated = new ServerVariable<DateTime>("$updated");
    }

   
public class ServerVariable<T>
    {
       
private readonly string _name;
        
public ServerVariable(string name)
        {
            _name = name;
        }
        
public string Name
        {
           
get { return _name; }
        }
        
public static implicit operator ServerVariable<T>(T value)
        {
           
throw new NotSupportedException();
        }
        
public static implicit operator T(ServerVariable<T> value)
        {
           
throw new NotSupportedException();
        }
    }

--
You received this message because you are subscribed to the Google Groups "re-motion Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/re-motion-users/-/2KsbqHJ9m-0J.
To post to this group, send email to re-moti...@googlegroups.com.
To unsubscribe from this group, send email to re-motion-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/re-motion-users?hl=en.

Gordon Watts

unread,
Jan 3, 2013, 9:37:32 PM1/3/13
to re-moti...@googlegroups.com
Hi,
  I’m sorry this took so long to get back to you.
 
  So, I had a problem where a the Enumerable.Range was improperly translated (this is a static method call). So, I created a special expression to capture it with the semantics I wanted. What you want to do is very similar.
 
  First, I had to create a new expression that re-linq could put in its expression tree and parse correctly. This derives from ExtensionExpression, and the code for it can be seen here:
 
 
  Now, I had to look at the query model early in the translation process to make sure that I caught the Enumerable.Range expression and correctly translated it before the rest of re-linq’s machinery got a hold of it. This meant creating a IExpressionTransformer object. For me the Enumerable.Range is a method call, so mine was setup to be invoked for all method call’s. It would do some quick checks and bail without slowing things down. You’ll need to do something similar for a property lookup instead of a method call. The code for this can be found here:
 
 
  Finally, you have to insert this expression transformer into the list of transformers near the start of the query model processing. You can see the code I used to do that in the CreateLINQToTTreeParser method here:
 
 
  I hope this is helpful!
 
Cheers,
        Gordon.
 
Reply all
Reply to author
Forward
0 new messages