Friday 22 July 2011

linq to lucene magic unicorn edition

This week I started to look at using Lucene.Net again in a project. Previously I have used it directly however whilst on the new look Lucene.Net website I noticed the linq to lucene project. Which at first look seemed pretty good. However upon looking at the source I found it only works with XML and LinqToSql, this prototype project however was in .Net 4 and used Sql CE4 with Entity Framework 4.1 Code First.


Rather than abandon linq to lucene I decided it should be easy enough to get it working with EF4.1. DatabaseIndexSet contains the LinqToSql specific code so for the purpose of producing a proof of concept this is where all the changes go.


The first item to change is to rescope the generic where clause to be DbContext rather than the linq context.


 public class DatabaseIndexSet : IndexSet
        where TDataContext : DbContext

Next the Write Method needs altering, the LinqToSQL implementation uses the GetTable method, however E.F doesn't really have the same methods. Instead with E.F we can use the Set method with our entity as the generic, this will allow us to obtain all of the records


Finally the GetTableTypes method needs "tweaking", I say tweak as so far its a bit of bodge. The GetTableTypes method is used to find all of the "tables" within our database context which are then later used to create lucene index files. The original LinqToSql method ensured that each property was a generic type and that it is assignable from the base type. For our initial run as our entity classes don't inherit anything I have removed that check, just ensuring the properties are generic. This will be added back in for the final release.


With those changes made we can then use LinqToLucene as follows:


 var index = new EnquiriesIndexContext();
            index.Write();
            var query = from p in index.Parts
                        where p.PartNumber == "ghjtyugfhj-61"
                        select p;
           Console.WriteLine("Simple Query:");
           ObjectDumper.Write(query);
           Console.WriteLine("Query Output: {0}", query.ToString());
           
            var results = query.ToList();
            Console.WriteLine("SimpleDemo returned {0} results", results.Count);


Have a go of the prototype code that is attached, I'll be aiming to tidy it up and get it pushed back to the main project on codeplex over the next week. Enjoy

1 comment:

Daniel said...

I would love to see if you did anymore work with this.