Interacting with databases has never felt all that natural to me. I've tried using several flavors of object-relational-mapping tools, I've tried writing my own mapping objects, and I've tried most flavors in between. And, while most of the accepted approaches had their strengths, they usually left me feeling a bit empty.
For years I've tried to figure out what it was about these techniques that didn't seem quite right. Certainly, many of these approaches were relatively good at performing basic create, read, update, and delete operations. It would also be fair to say that these tools seemed to do a reasonable job of limiting the amount of time I had to invest in writing SQL.
So, why, if these tools were so adequate, did they still leave me wanting more?
I never answered these questions for myself and I'd kind of given up hope and accepted the status quo. Then, when I wasn't really looking for an answer, I found one. For me, it came in the form of Microsoft's Language Integrated Query (LINQ).
With LINQ, which is currently avail-able in beta release, Microsoft seems to be openly acknowledging the fact that building yet another mapping tool would have been pointless. If they were going to make substantive, meaningful strides in the area of querying and accessing data, they had to take a step back and look at how the .NET languages could be enhanced in a way that would promote more natural and dynamic forms of interaction with all types of data.
The example shown in Figure 1 helps highlight what I'm getting at here. The syntax of this sample query, which uses LINQ to find items in a collection, shouldn't be all that foreign. LINQ queries leverage all the fundamental concepts that are part of traditional query languages.
If you've done any SQL at all, the select, from, and where clauses in this query should look very familiar. However, instead of cobbling these elements together into some query string, I am able to construct my expression using built-in language constructs.
LINQ's query syntax isn't earth-shattering, but you have to admit it's quite a leap forward from the days of shipping out SQL strings and praying they wouldn't blow up at run time. It's very comforting to know that each query I write will be treated as a first-class citizen in the .NET run time. In fact, with LINQ, each of these queries will be fully validated at compile time.
I also like the idea that LINQ doesn't force me to learn yet another complex hierarchy of classes to assemble and execute my query. In fact, when I look at LINQ queries, I don't see classes and methods--I see an expression. Overall, I think this dynamic makes LINQ very approachable and intuitive.
LINQ also brings a new perspective to what it means to "query" a data source. In the world of LINQ, a query is not limited to any particular kind of data. LINQ allows queries to be applied universally to any number of different data structures.
With LINQ I can construct queries to execute against in-memory collections, XML (via XLINQ), and relational data-bases (via DLINQ). In fact, you'll notice that the example in Figure 1 is actually performing its query against a list of objects. This built-in ability to create a unified view of data across many domains is one of the most intriguing and powerful aspects of LINQ.
The element of LINQ that really pushed me over the edge, though, was the language's ability to create anonymous types to hold the output of a query (see Figure 2).
The key area to focus on in Figure 2 is the select clause. Here, the new keyword is used to indicate that the query results will be stored in a dynamically declared, anonymous type. This new type has two properties, upper and lower, that hold the upper and lowercase representations of the words from the supplied collection.
Creating these anonymous types on the fly really brings a whole new dimension to my interactions with the data domains. Whereas traditional mapping techniques would require me to work with canned representations of the objects returned by a query, an anonymous type gives me the freedom to construct objects of any type or shape on the fly.
These anonymous types acknowledge a reality in my environment that other object relational tools did not. Anonymous types recognize that the shape and structure of the data I want returned from a query can vary. If I have a query that accesses customers, orders, and invoices, and I want my query to return some subset of the data from these tables, I can use anonymous types to define the exact structure that will be used to represent the results of that query.
As you can imagine, this technique eliminates the need to pollute my pool of data objects with one-off, custom variants. Anonymous types allow me to create as many special representations as I need. They also eliminate the need to create a fully populated data object when I only want to access a subset of its attributes.
Of course, these anonymous types also remain true to the type-safety mantra that is a big part of the LINQ implementation. So, even though the compiler will be emitting new types to support your query, it will still fully validate them at compile time.
The power of anonymous types combined with this somewhat agnostic approach to data sources--all achieved through type-safe, language-integrated constructs-makes LINQ very intriguing. By stepping back and attacking query at the language level, I believe LINQ will create a fundamental shift in how .NET developers view the role of queries in their applications.
Even more exciting to me, though, is the fact that LINQ is just one of many efforts that are actively attempting to equip developers with better, more dynamic mechanisms for accessing data. The Rails community, for example, is also making strides in this same space. And, while none of these approaches may solve all of our problems, it's certainly encouraging to see so many mainstream tools making a real effort to move us all forward.
What influence will dynamic language constructs and integrated query concepts have on your approach to representing and accessing data in your solutions?
Join the conversation below or start a new one in the Reader Comments section.