Hi Guys, I have the following model class Assignment [Field] bool Active [Field] DateTime Start [Field] DateTime? End Current The implementation for Assignment.Current is: get { return Active && Start <= DateTime.Now && (End == null || End.Value >= DateTime.Now); } How can I write a custom LINQ expression rewriter for the Current property so that I can use the following LINQ query: Query.All<assignment>.Where(assignment => assignment.Current) I've tried to do it myself but the Expression stuff is new to me. Thanks for your help! Updated at 17.02.2010 23:38:06Hi Alex, Thanks for the help. This is the error I get with your code.
Also, the manual says to register the rewriter using
Also, if IQueryPreprocessor is a better option, where can I find more info? This thread was imported from our support forum. The original discussion may contain more detailed answer. |
First of all, I just fixed a bug related to usage of IQueryPreprocessor - it simply didn't work, and, as we discovered, there were no real tests for it except in Localization sample (it seems our guys have occasionally moved the code from tests to it). This must be interesting for you, even although this isn't related to your question at all: query preprocessors provide even more flexible way of doing such things (e.g. they allow you to inject filtering condition automatically for any query). So RC is updated once more, and localization sample works there now ;) Secondly, you need nearly the following code:
I didn't test this - I just adopted this code from sample from our Manual project (all the code provided in Manual is actually taken from it). Btw... Do you know that currently any method of LINQ rewriter must return the same expression for the same input, i.e. its methods must be pure functions. More precisely, if you' violate this, you'll definitely get issues with compiled queries. But it's ok to do this if you don't use rewritten expressions in compiled queries (i.e. use them just in regular LINQ queries). In future we'll offer an API allowing to properly cache produced query versions for compilers that aren't pure functions. > I'm assuming you autodetect them now. It must be registered as any other type - i.e. any type DO4 is interested in now must be added to DomainConfiguration.Types collection (DomainTypeRegistry, the reference is here). This isn't reflected in Manual yet, but we'll fix this until release. > Also, if IQueryPreprocessor is a better option, where can I find more info? For now you can see just Localization sample. In your particular case LINQ rewriters is more precise solution, but the same can be achieved with LINQ preprocessor as well. > This is the error I get with your code. Could you try to simplify the ex expression to isolate the bug? E.g. leave just a.Active part there, and then add other pieces of it. Most likely there is some issue related to handling of Nullable<t>.Value in translator - we'll try to reproduce it today as well. An example simplified expression can be e.g. this one:
The effect will be the same, taking into account null handling. v4.2 RC installer containing the bugfix is here: http://code.google.com/p/dataobjectsdot ... loads/list I did not publish this @ Xtensive, since I'm going to update it once more in the deep night today (Manual will contain few more sections, etc.). I used simply a => a.Active and it worked. If I use a => a.Start <= DateTime.Now, it does NOT work. Apparently DateTime fields can't be used (and therefore Nullable<datetime>). But ints, bools, etc work fine. Hmm... We're testing the issue. Most likely it is related just to translation of casting of an expression of DateTime type to Nullable<datetime>, since there are tests involving both DateTime and Nullable<datetime> in LINQ. We've just fixed an issue - it really was there (conversion + static property access was broken). So I'll update RC shortly, for now the changes are already @ Google Code. Fix confirmed. Thank you! DO4 is fantastic! |