Sunday, January 20, 2008

Demystifying C# 3.0 - Part 7: Expression Trees

source: http://blah.winsmarts.com/2006/05/23/demystifying-c-30--part-7-expression-trees.aspx
Demystifying C# 3.0 - Part 7: Expression Trees
Ending the series with a psshtt bang!! pop!
Posted on 6/30/2006 @ 8:47 PM in #Vanilla .NET 0 comments 3711 views
In this series of Demystifying C# 3.0 we have already covered -
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)
Thank you to both Eric Wise, and C. Steen for linking. The more people we have look at these posts, the better the overall discussion quality will be.
Okay, so next we will be talking about "Expression Trees". You must read about Lambda Expressions before you read this post.
So in short, Expression trees permit lambda expressions to be represented as data structures, instead of executable code. What that means is, a lambda expression such as
x => x + 1, is executable code. which could also be written as,
Func f = x => x + 1
But,
Expression> e = x => x + 1 ;
In other words, if a lambda expression can convert to a Delegate type "D", it can also convert to an expression tree of type System.Query.Expression.".. if a lambda expression can convert to a Delegate type "D", it can also convert to an expression tree of type System.Query.Expression.. " <-- That fills out that little blurb I left out when discussing Lambda Expressions.This covers the basics of C# 3.0. Next we will be continuing this talk, with a continued discussion on LINQ.

Labels: , , , ,

Demystifying C# 3.0 - Part 6: (LINQ) Query Expression Translation (to C# 3.0)

Source: http://blah.winsmarts.com/2006/05/21/demystifying-c-30--part-6-linq-query-expression-translation-to-c-30.aspx
Demystifying C# 3.0 - Part 6: (LINQ) Query Expression Translation (to C# 3.0)
Posted on 6/30/2006 @ 8:47 PM in #Vanilla .NET 7 comments 5310 views
In this series of Demystifying C# 3.0 we have already covered -
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 Initializers
I *strongly* recommend reading up the above in sequence before reading this post. This is, (I feel) a rather good post, that will set LINQ in your mind clearly. If you rush through this post, you will waste this opportunity. If you are crystal clear about the above 5 posts and the concepts behind them, .. read on ..
Okay good, so in this post, we are going to talk about "Queries" or "LINQ" for the very first time in this Demystifying C# series. I have been asked in comments to talk about the practical application of the new C# 3.0 thingies. I can come up with seemingly lame practical applications, because the real awesome practical application - IS - LINQ (Language Integrated Query).
The practical application of the above 5 C# 3.0 features (which are not the complete set of new things in C# 3.0), can best be understood by understanding Query Expression Translation.
LINQ, as you may already know, looks like TSQL queries, except they are twisted upside down, and written in right inside of C#. You have probably already heard about the benefits, so I won't go into those for now. In here, we are going to talk about Query Expression Translation. You can write queries in LINQ using various keywords such as "from", "where", "select" etc.
Those queries, get translated into plain vanilla C# 3.0 code, and only then type-binding, overload resolution etc. happens. Once the Query has been translated to C#, it is then executed as regular method invocations - where of course you have various C# protections such as a method being missing, data types mismatched so on and so forth.
So, LINQ --> Query --> TranslatedToC#3.0 --> Method Invocation.
So LINQ = Method Invocation? YES - THAT IS WHAT MAKES LINQ, Nothing but Plain vanilla C# 3.0. All those new language constructs, along with Query Expression Translation, make LINQ possible.
Lets understand with the help of an example.
In my last post Demystifying C# 3.0 - Part 5: Object and Collection Initializers, I had a simple example demonstrating Object & Collection Initializers. Basically, we got a List back as shown below -
var theWhiteHouseStaff = new List { new Monkey{ Name = "George W Bush", Age = 16}, new Monkey{ Name = "Donald Rumsfield", Age = 16}, new Monkey{ Name = "Condolezza Rice", Age = 16}, new Monkey{ Name = "Dick Cheney", Age = 16} } ;
It is notable that List implements IEnumerable, so the above is a queryable object. So, you could write a query, that looks like -
var q = from staff in theWhiteHouseStaff select new {staff.Name} ;
Practical Application: "var q" <-- Anonymous Type (+). An anonymous type that holds an Anonymous Type with one property "staff.Name". Also, "var" lets you create an Implicitly typed local variable (+) . This means, a) You didn't have to declare/write a class structure to hold a type with one property called "Name" of data type string. b) You don't have to maintain that either - you can change the structure of the above query, and "it just works" :)
Now, the above query, can also be written like this -
var q = from staff in theWhiteHouseStaff select new { Name = staff.Name } ;
Practical Application: "new { Name = staff.Name }" <-- Object Initializer (+). The anonymous type, is being initialized by an Object Initializer. The anonymous type doesn't have logic, or a constructor. But it does have public setters on it's properties, so there you go - the Object Initializer can now take advantage of those, and the query is slowly decomposing into plain vanilla C# 3.0.
The above query, further decomposes into the below -
var q = theWhiteHouseStaff.Select(staff => new {staff.Name}) ;
WHOAA !!!, lets look at this query once again, only color coded this time ;-)
var q = theWhiteHouseStaff.Select(staff => new {staff.Name}) ;
(PS: If the RSS Feed eats the color coding, I suggest you come see it on my blog)
Practical Application: The yellow var q, is an Anonymous Type (+) "q", the "var" lets you create an implicitly typed local variable (+). The theWhiteHouseStaff is an IEnumerable The green Select is an Extension Method (+). The Gray staff => new { staff.Name } is a Lambda expression (+) that is participating in type-inference (+). and the new {staff.Name} is an Object Initializer (+).
So, the LINQ Query
var q = from staff in theWhiteHouseStaff select new {staff.Name} ;
is *absolutely* the same as the C# 3.0 language construct -
var q = theWhiteHouseStaff.Select(staff => new {staff.Name}) ;
Thus, the (Linq) query expression has been translated (to plain vanilla C# 3.0). This is called as Query Expression Translation, and this is the reason behind C# 3.0 enhancements. :)Cool huh?

Labels: , , , ,

Demystifying C# 3.0 - Part 5: Object and Collection Initializers

Source:http://blah.winsmarts.com/2006/05/21/demystifying-c-30--part-5-object-and-collection-initializers.aspx
Demystifying C# 3.0 - Part 5: Object and Collection Initializers
Posted on 6/30/2006 @ 8:46 PM in #Vanilla .NET 0 comments 2639 views
As you may already be aware, I am writing up a series of posts on C# 3.0/LINQ and DLINQ, that intend to bring these technologies down to a simple, easy to digest, understandable form. These will be served in small bite sized peices - 5 minutes of your time everyday, and little strokes will fell great oaks. (I am still talking about C# 3.0)
So in this series, we have already talked about -
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 Expressions
Today, lets talk about "Object and Collection Initializers"
First Object Initializers
Lets say, you had a class as shown below -
public class Monkey{ private string monkeyName; private int age; public string Name { get { return monkeyName; } set { monkeyName = value; } } public int Age { get { return age; } set { age = value; } } }
The above can be easily instantiated as shown below -
var gwBush = new Monkey{ Name = "George W Bush", Age = 16} ;
The above code simply calls the "setters" of "Monkey" to give you a variable called gwBush back. Note that there is no constructor that accepts the public properties as arguments.
Next, Collection Initializers
Collection initializers, are the corollary of how you'd initialize arrays. Put simply, you can initialize a collection as shown below -
List digits = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
So what is the practical upshot of this?
Look at this one line of code -
var theWhiteHouseStaff = new List { new Monkey{ Name = "George W Bush", Age = 16}, new Monkey{ Name = "Donald Rumsfield", Age = 16}, new Monkey{ Name = "Condolezza Rice", Age = 16}, new Monkey{ Name = "Dick Cheney", Age = 16} } ;
Boy that sure looks a lot cleaner than a number of temporary variables, hanging chads and recount in florida etc. .. in other words, a much cleaner and terse syntax.

Labels: , , ,

Demystifying C# 3.0 - Part 4: Lambda Expressions

Source: http://blah.winsmarts.com/2006/05/19/demystifying-c-30--part-4-lambda-expressions.aspx
Demystifying C# 3.0 - Part 4: Lambda Expressions
Posted on 6/30/2006 @ 8:43 PM in #Vanilla .NET 2 comments 5819 views
In the Demystifying C# 3.0, I've already talked about -
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 Methods
Lets next talk about Lambda Expressions.
The best way I can describe Lambda Expressions are - C# Anonymous Methods, only a lot cooler.
So what is an anonymous method in C# 2.0?
Well y'know you can write code like below in C# 1.x/2.x -
class SomeClass{ delegate void SomeDelegate(); public void InvokeMethod() { SomeDelegate del = new SomeDelegate(SomeMethod); del(); }
void SomeMethod() { Console.WriteLine("Hello"); }}
Well, anonymous methods let you write the above code in a much more "convenient to write terse way" as below -
class SomeClass{ delegate void SomeDelegate(); public void InvokeMethod() { SomeDelegate del = delegate() { Console.WriteLine("Hello"); }; del(); }}
Wunner'ful. What you see above after the "delegate()" stuff is an anonymous method. Even though it's better than the C# 1.x version, it is still quite verbose.
Lambda expressions give you an even more concise, functional syntax using the"=>" token. In fact, the above could now simply be written as
class SomeClass{ delegate void SomeDelegate(); public void InvokeMethod() { SomeDelegate del = () => Console.WriteLine("Hello") ; del(); }}
In general, the syntax is
parameters => expression
Now obviously, even though this is terse, frankly I don't know how you feel about it - I think changing syntax just for the heck of it, dude that's so not cool!! Now it turns out, Lambda expressions aren't simply a cool new way of writing anonymous methods. They are in fact, a functional superset of anonymous methods. Why?
Lambda expressions can "infer" parameter types, even if you omit them. Anonymous methods bitch and moan if you miss out any parameter explicitly.
Lambda expressions can use both statement blocks and expressions. Anonymous methods take only statement blocks - thus making lambda expressions a tad bit more convenient to use.
Lambda expressions can be passed in as arguments. And when you do so, they participate in "Type argument inference" and "method overload resolution" - (WHOAA what are these 2 heavy duty sounding words? - Sit tight, we'll talk about them soon-ish).
Lambda expressions with an expression body can be converted into expression trees. Expression trees is .. well, we haven't discussed that yet ~ so we'll discuss that, when I write a blogpost about Expression Trees.
Lets talk about these one by one -
Lambda expressions can "infer" parameter types, even if you omit them. Anonymous methods bitch and moan if you miss out any parameter explicitly.
Heavy duty words for something as simple as -
(int x) => x + 1 ; // is the same asx => x + 1 ;
In the second instance, the type is being inferred.
Lambda expressions can use both statement blocks and expressions. Anonymous methods take only statement blocks - thus making lambda expressions a tad bit more convenient to use.
Again, heavy duty words for something as simple as -
(int x) => x + 1 ; // is the same as(int x) => { return x + 1; }
In the second instance, we have a statement block, and in the first we have an expression. So the first - is the same as the below, but it is terse and easier to write and understand.
Lambda expressions can be passed in as arguments. And when you do so, they participate in "Type argument inference" and "method overload resolution"
You could pass in Lambda expressions as arguments into a generic method. Lets consider this in an example. Lets say, you had an extension method (what are extension methods?) as shown below -
public static class myExtensions{ public static void SpankIt( this IEnumerable source, Func someParameter) { foreach (T element in source) Console.WriteLine("SPANK " + someParameter(element) + "!!"); }}
You could use the above Extension method a bit like this -
static void Main(string[] args){ List whoToSpank = new List() ; whoToSpank.Add("Monkey") ; whoToSpank.Add("Bannana") ; whoToSpank.SpankIt(c => "Monkey") ;}
And this produces "SPANK MONKEY !!" twice.
But wait a minute. What is "U" in the extension method? If you put a breakpoint in your extension method, you will find out that C# 3.0 is smart enough to infer that "U" is a string. Dude, you never said "String" it "inferred" it based upon what lambda expression you passed in.
You can't do that with anonymous methods, now can you?
Overload resolution is very similar to this, so I will skip explaining that. And yes there are clear laid out rules regarding overload resolution and type-inference, refer to the C# specs for that (I hate regurgitating docs).
Finally -
Lambda expressions with an expression body can be converted into expression trees. Expression trees is well just read this post instead.

Labels: , , ,

Demystifying C# 3.0 - Part 3: Extension Methods

Source: http://blah.winsmarts.com/2006/05/18/demystifying-c-30--part-3-extension-methods.aspx

Demystifying C# 3.0 - Part 3: Extension Methods
Posted on 6/30/2006 @ 8:41 PM in #Vanilla .NET 2 comments 4014 views
If you've been following my blog, you would have noticed that I've been trying to talk about new C# 3.0 features one by one. I am trying to take the technical jargon out, and bring these features down to an understandable level.
You may want to read the two features I have already talked about below -
a) Demystifying C# 3.0 - Part 1: Implicitly Typed Local Variables "var"b) Demystifying C# 3.0 - Part 2: Anonymous Types
So here goes, Part 3: Extension methods.
Frequently you are handed a class, such as System.String, or System.Int32, that you "wished" had that one extra method that would make your life so much easier - but damn it doesn't have that method. In certain instances you can inherit and add, but you know that is tougher than it sounds in many cases (abstract/virtual), and in certain cases impossible (sealed).
Extension methods, solve that problem. You can now add newer methods, specific to your business domain - to existing types, that you did or didn't write.
So if you wanted an extra method called "SpankMonkey", you could now write code like below
int i = 10 ;i.SpankMonkey() ; // Spanks the monkey per the logic you wrote.
How neat !!! But don't go around misusing this *feature*, because Extension methods are both less discoverable and more limited in functionality than plain vanilla instance methods such as ToString(). Use them only if you must.
So how do you write an extension method?
Well thats easy, you simply put the "this" keyword as the first parameter of the extension method ~ which is a static method in a class. So you could write code as below
public static class myExtensions{ public static void SpankMonkey(this int i) { Console.WriteLine("SPANK!!"); }}
Sure you could have complicated implementations such as -
public static int DoubleMe(this int i){ return i + i ;}
You could call the above using -
int i = 10;Console.WriteLine(i.DoubleMe()) ; // Prints 20
You could also pass in a "generic" instead of an "int" or "string" etc.
Extension Method Resolution:
An obvious question here is, what if your class implements a method, AND there is an extension method that looks, talks, walks the same way - that is of the same name? Which gets called?
The answer is - "Whichever is the closest". In other words,
Strongly Typed instance methods _will_overrule_ Strongly Typed extension methods _will_overrule_Not Strongly Typed instance methods _will_overrule_Not Strongly Typed extension methods.
Whoaa that's confusing. :)
This code makes it easy to eat the above 4 lines.
public static class E{ public static void F(this object obj, int i) { } public static void F(this object obj, string s) { }}
public class A { }

public class B
{
public void F(int i) { }
}
public class C
{
public void F(object obj) { }
}
public class X
{
public static void Test(A a, B b, C c)
{
a.F(1); // E.F(object, int) is called
a.F("hello"); // E.F(object, string) is called
b.F(1); // B.F(int) is called
b.F("hello"); // E.F(object, string) is called
c.F(1); // C.F(object) is called
c.F("hello"); // C.F(object) is called
}
}
Of course if nothing matches, you get a compile time error (duh!)Neat !! So now we know what "Extension methods" are, how you can write them, how you can use them, and how they may be called.Next we'll be talking about Lambda Expressions. See ya around !! :-)

Labels: , , ,

Demystifying C# 3.0 - Part 2: Anonymous Types

Source: http://blah.winsmarts.com/2006/05/17/demystifying-c-30--part-2-anonymous-types.aspx

Demystifying C# 3.0 - Part 2: Anonymous Types
Posted on 6/30/2006 @ 8:41 PM in #Vanilla .NET 8 comments 4497 views
In my last blog entry, I had talked about Implicitly typed local variables and the "var" keyword. If you have stumbled across this post through a search engine, or otherwise, I would recommend reading that first.Assuming that you understand "var" - lets dive into part 2 of Demystifying C#3.0 ~ Anonymous Types.In C# 2.0, lets say you wanted to represent a person, you would typically have to write a class as follows -public class Person{ string hairColor ; string skinColor ; int teethCount ;} // I'm obviously taking the shortcut by not creating properties .. anyway, that's besides the point.Well, in LINQ, I could be querying arbitrary groups of my data. When I'm querying "Customers", and the above is a subset of "a customer" - what a royal pain in the rear it would be if I had to first write the structure of my class, before I can use the class? (Duh!). While that sounds like "the thing to do" - you immediately lose the ability to query any arbitrary structures of data at runtime.Enter anonymous types. Now you can represent arbitrary clumps of data, without having to declare their structure first. Here is how.var monster = new {hair="black", skin="green", teethCount=64} ;The above line of code will work even if you do not declare a class called "Person" in advance. This lets you arbitrarily create newer structures to represent your data, without having to define them at "coding time" first.The above line of code simply generates a class under the scenes (you never see it), that looks like as below - class __Anonymous1{ private string _hair = "black"; private string _skin = "green"; private int _teeth = 64;
public string hair {get { return _hair; } set { _hair = value; }} public string skin {get { return _skin; } set { _skin = value; }} public int teeth {get { return _teeth; } set { _teeth = value; }}}Thus this class is an "Anonymous Type" - it has no name, it was generated for you by the C# compiler, so you can represent and hold any arbitrary clump of data, but yes it is a "System.Type".The rationale behind the creation of this was to be able to query for any arbitrary set of data, without having to declare it's structure first. That would be a bit essential for LINQ I'd say ;-).

Labels: , , ,

Demystifying C# 3.0 - Part 1: Implicitly Typed Local Variables "var"

Source:http://blah.winsmarts.com/2006/05/17/demystifying-c-30--part-1-implicitly-typed-local-variables-var.aspx
Demystifying C# 3.0 - Part 1: Implicitly Typed Local Variables "var"
A 5 minute a day;digestable blog series.
Posted on 6/30/2006 @ 8:40 PM in #Vanilla .NET 8 comments 5407 views
I am going to publish a series of blogposts that intend to bring C# 3.0 down to earth. C# 3.0, along with LINQ, and all the heavy duty talk that surrounds it has sort of made it difficult to understand IMO. Well - if not difficult to understand, it sure is tough to gauge - "Where to begin".So with 5 minutes a day, a short post a day will dice and slice a single feature, and we will logically move to a fuller picture of C# 3.0, followed by LINQ, and DLINQ (if I still have steam left).So here we go, with the first in that series, the "var" keyword.In C# 2.0, you can declare an integer (or anything for that matter of fact) as - int i;You could also write something like - int i = 1;Generally speaking - = ;Okay good. The important thing to realize is that "i" is an integer. In C# 3.0, the below is a valid statement - var i = 1;But what is "var"? "var" is .. umm .. a keyword, that results in "i" being of the same data type, of the initializer ~ in this case an integer. So, var i = 1; will result in creating a variable called "i", whose data type is "integer".But then what is the difference between "var", "object" and "variant" (from COM or VB6 days).Variants were oink oink piggies, basically a catch all pig that occupied way too much memory. Objects have boxing unboxing issues. Both Variants and Objects are not strongly typed.Note that "i" is strongly typed to an integer—it is not an object or a VB6 variant, nor does it carry the overhead of an object or a variant. To ensure the strongly typed nature of the variable that is declared with the var keyword, C# 3.0 requires that you put the assignment (initializer) on the same line as the declaration (declarator). Also, the initializer has to be an expression, not an object or collection initializer, and it cannot be null. If multiple declarators exist on the same variable, they must all evaluate to the same type at compile time.You could also create "arrays" of "vars" as follows - var intArr = new[] {3,1,4,1,5} ;Great !!! I hope this clarifies a bit what "var" is, in my next post, we will see what "Anonymous Types" are.

Labels: , , ,

Demystifying DLINQ: Part1 - An introduction to DLINQ

Source:http://blah.winsmarts.com//2006/06/02/demystifying-dlinq-part1--an-introduction-to-dlinq.aspx

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: , , ,