That said, let's play with the application for a while and them dig a little bit in its code.
How to use it ?
First, download the code here and compile it (any version of Visual Studio 2008 can be used).
Now populate a db4o database (with data) and copy the an assembly containing the types stored in that database to the LinqConsole.exe folder.
You will need to copy your model assembly to
LinqConsole executable directory, otherwise it
will not be able to find it.
Start the application and, once presented the prompt (>), enter commands (prefixed with ":") or a query (finished with ";"). The very first command you may want to try is :help to see a list of valid commands (type :help and press
- the database file to query (through database command)
- the assembly containing the types stored in the database; we call this assembly, model assembly because usually, it will hold your business objects (the model in MVC pattern). Unfortunately, this assembly must be in the same directory as the application, otherwise the application will not be it able to find it (technically one can configure the application using Linq.Console.exe.config file to allow assemblies to be stored in alternative directories).
from Type t in database select t;
Before leaving this topic, I'd like to call your attention that in order to Linq for db4o to work you need to specify a type in the query (that's the entry point for our custom "Linq Provider"), otherwise, you will get an error like the one bellow:
Note that in this case I've omitted Person type in the query, i.e, I've typed:
from p in database select p;
from Person p in database select p;
How it works ?
The basic idea behind this application is pretty simple: Given a model assembly (specified through load command), a db4o database (specified through database command) and a Linq query, find all types and namespaces defined in such assembly them emit code to run the query against the database.
In CompileQuery() method we emit a new type (TheQuery) using the specified values (database, namespace and query). This type implements IInteractiveQuery interface, so, after instantiating it we call its Run() method to execute the query.
In order to dynamically compile this type (TheQuery) we use classes defined in System.CodeDom.Compiler and Microsoft.CSharp namespaces; any compilation errors will be rendered in red on yellow background text.
Well, I must admit: in its current state, this program has some limitations (but most of them are there to allow you to play with it ;)
From the top of my head, I can came up with a list (of coarse, not an exhaustive one) of possible improvements:
Support model assemblies in other directories
Currently in order to use a model assembly, users are required to copy it to the application folder.
- Check if the types stored in the database can be found in the model assembly.
- Better error handling in general
- Warn users about invalid commands Currently nothing happens for invalid commands (no message).
- List types inside an assembly A new command (for instance, types) could be added to allow users to list the types contained in an assembly.
- Add support to query Db4o in server mode.
- Auto-completion This probably would require major changes in the input handling, but it would be nice to add auto-completion to list types, assemblies, databases, etc. in the commands.
- You name it! The sky is the limit :)
I really expect that you enjoyed this application; if you have questions/suggestions please, fell free to drop me a line :)