Tuesday, December 27, 2011

LINQ To LDAP: Visiting the Locals

I recently ran into a problem with how LINQ to LDAP's expression visitor was working. This expression:
source.Where(u=> objectGuid.HasValue && u.objectGuid == objectGuid.Value)
was throwing a NullReferenceException. The problem was related to that first condition. The visit constant for QueryTranslator was making an assumption that for each constant it found there would be a corresponding member access.

My hackish solution was simply to ignore constants that don't have a corresponding property. Well that worked, but I saw two problems. First it created unnecessarily complex filters (& and | where one wasn't necessary). The second issue was the InvalidOperationException caused when .Value was called for a nullable without a value.

So fast forward several days of on and off coding (Christmas is for family and coding!) and I think I have a solution. I already borrowed the SubtreeEvaluator so I just needed to create a visitor that would rewrite only boolean constants. Well, I ended up creating two. One to rewrite and then another to remove redundant and unnecessary values. When I finish refactoring, you'll be able to find the BooleanRewriter and BooleanReducer in the Visitors folder.
//if objectGuid doesn't have a value the expression will reduce to:
source.Where(u=> false)

//if objectGuid has a value then the expression will reduce to:
source.Where(u=> u.objectGuid == objectGuid.Value)