Sunday, January 20, 2008

Demystifying DLINQ: Part1 - An introduction to DLINQ


Demystifying DLINQ: Part1 - An introduction to DLINQ
Here we go, another 5 minute a day series.
Posted on 6/30/2006 @ 8:53 PM in #Vanilla .NET 4 comments 6640 views
I hope you enjoyed my series on Demystifying C# 3.0. The idea being, 5 minutes a day, a small digestible post, that gets the point across.
a) Demystifying C# 3.0 - Part 1: Implicitly Typed Local Variables "var"b) Demystifying C# 3.0 - Part 2: Anonymous Typesc) Demystifying C# 3.0 - Part 3: Extension Methodsd) Demystifying C# 3.0 - Part 4: Lambda Expressionse) Demystifying C# 3.0 - Part 5: Object and Collection Initializersf) Demystifying C# 3.0 - Part 6: (LINQ) Query Expression Translation (to C# 3.0)g) Demystifying C# 3.0 - Part 6: Expression Trees
Having taken a small break, and pondered a bit on the future direction of Demystifying *.* posts, I reached the conclusion that a Demystifying LINQ series didn’t make too much sense. The best way to learn LINQ is simply by using it. It’s a question of learning a number of query structures, and their translation to C# 3.0.
And guess what, we will be doing that anyway, in this new series –
Demystifying DLINQ
So welcome to Post #1 – “An introduction to DLINQ”. If you are new to the Demystifying series, I would strongly recommend reading up on my previous Demystifying C# 3.0 posts.
So, What is DLINQ?
DLINQ is that component of the LINQ infrastructure, that provides a run-time infrastructure for managing relational data as objects without giving up the ability to query.
I’d like you to focus on the last phrase – without giving up the ability to query.
Well, some of us are DataSet oriented, and some of us are business objects oriented. Many business object lovers criticize a DataSet as being useless/worthless. You guys couldn’t be any more stupider.
See, both DataSets and Business Objects have their own advantages and disadvantages. What you business object hippies choose to ignore is that, in writing your BOs, you do gain the ability to represent your data in a more meaningful semi-structured hierarchical form, but at the same time, you have to write every damn thing yourself. You have to write your own persistence, hydration logic (ignoring the ORMs out there), and at the very heart of it, you loose the ability to query your data.
So you end up writing everything yourself, custom to your domain, and argue that it’s better than a DataSet. Well DUH!! For the effort you put into it, it better be. (Please also read - Are you a business object person, or a DataSet person).
But that is where DLINQ comes in – it lets you work with your Data, as Business Objects, without giving up the ability to query your data.
Here is a rather simple example demonstrating what I’m talking about.
Suppose you had a really simple BO that could be represented using the following code –
public class Customer{ public string CustomerID;
public string City;}
Well, decorate it with a few attributes and you get this –
[Table(Name="Customers")]public class Customer{ [Column(Id=true)] public string CustomerID;
[Column] public string City;}
And now you can query your data like this –
// DataContext takes a connection string DataContext db = new DataContext("c:\\northwind\\northwnd.mdf");
// Get a typed table to run queriesTableCustomers = db.GetTable();
// Query for customers from Londonvar q = from c in Customers where c.City == "London" select c;
The DataContext class allows you to represent an abstraction of your database, and guess what – you can strongly type it as follows –
public partial class Northwind : DataContext{ public TableCustomers; public TableOrders;
public Northwind(string connection): base(connection) {}}
Which then simplifies your querying to as follows –
Northwind db = new Northwind("c:\\northwind\\northwnd.mdf");
var q = from c in db.Customers where c.City == "London" select c;
foreach (var cust in q) Console.WriteLine("id = {0}, City = {1}",cust.CustomerID, cust.City);
Gotta say, that’s pretty neat ;-).
Practical Tip: Now it is important to realize that “var q” is not a Query, it is merely the potential to execute a query. The query executes in the foreach – very much like a data reader. And yes you guessed it right – it makes sense to keep that loop tight for connection pooling reasons.
A few things jump out straight away –
a) This code is fully strongly typed, none of that embedding SQL Queries as strings with no compile time validation.
b) I am working with a Business Object, not a dumb bucket of rows and columns (read DataSet).
c) But what about other OO concepts like Inheritance/Data hiding?
d) What if you inherited a stored procedure oriented system, or your DBA insists on enforcing security via stored procedures (which is quite lame), and your NTM (Non-tech-manager) agrees with him (which is real life).
e) How do I know if the query being executed is efficient or not?
f) How do I save changes back into the database? How do I do conflict detection and resolution/Concurrency checks?
g) If I’m working with a DataContext, how would querying and persistence work in ASP.NET, where I would theoretically need two separate DataContexts – one during Page_load, and the other during Page_Load with PostBack = true?
Damn that’s a lot of questions – and there will probably be more – which will all get answered in this Demystifying DLINQ series.
Stay tuned.

Labels: , , ,


Post a Comment

Subscribe to Post Comments [Atom]

<< Home