I use LINQPad a lot. Whether as a scratchpad or for fast, capable and interactive exploration of data, it's hard to beat. A LINQPad query is executed within a single 'data context' - typically a connection to a database, but there are many other creative uses of the feature. The data context drivers you can use with LINQPad are a big part of what makes it so useful - point one at a new database and instantly get strongly-typed access to its contents for seriously productive querying.
Given the 'one-context-per-query' constraint, when I'm working with several data sources, or performing time consuming transformations and analysis that I don't want to repeat all the time, I often serialise intermediate results and outputs to disk in JSON form for use later. Unfortunately, for nice strongly typed access, the downstream query needs access to the class definitions for the serialized types, which means either clogging up your
MyExtensions.dll with definitions for every little project, or copying them around, leading to general inconvenience and synchronisation concerns if you want to go changing your model later on. As I often have to work within the constraints of a
net40 environment (relevant implication: no F# + type providers), time and again I've yearned for a way to cut out that wasteful time spent generating C# classes for all my inputs, and the pyschological baggage of carrying them around my queries (not really though).
Fortunately, there's now an answer! I've just released the first alpha of a dynamic JSON data context driver for LINQPad. It uses the magic of the jsonclassgenerator project to build C# class definitions for your inputs, then turns them into a data context for your LINQPad query. You can add any number of sources to the context, either individual files, search directories with a filemask, or a combination of both, and after being sampled they appear as database tables would for any other data context driver, awesome!
In this initial release the basic functionality is there, and as long as the root element for each input is a JSON array, it should work pretty well. Still, there are plenty of things I want to add in the near future:
Edit: Many of these features are now included in the driver. For the latest description of functionality, check the project on github.
- support for grabbing JSON from the world wide web (GET or POST with parameters and/or request body)
- support for caching of deserialised data, as well as programmatic invalidation of cached data
- support for persisting new data to the context (for example, written to path in the context's search definitions), allowing you to build out your context as you go
- better support for class generation when encountering 'nested listitem' JSON inputs. For example, the current implementation will faithfully generate a set of classes for json like this that includes a root object with a single 'data' property under which the list of entities actually exists. This is true to the input but does not work well with our 'root JSON array' requirement, and will probably break things
- fixes for JSON data that it chokes on (if you have samples, please add an issue!)
- better error handling and no modal error dialogs (please forgive me, gods of UX).
You can grab the latest release here, or check out the source code. Contributions welcome!