Wednesday, July 2, 2008

Building blocks and Data sources of LINQ - Part 1

Building blocks and Data sources of LINQ - Part 1

The LINQ foundation consists of a set of building blocks including query operators, query expressions, and expression trees, which allow the LINQ toolset to be extensible.

You can plug a wide array of data sources into LINQ, including

  • File System
  • Active Directory
  • WMI
  • Windows Event Log
  • Any other Data Source or API

Microsoft already offers more LINQ providers

  • LINQ to Objects is an API that provides methods that represent a set of standard query operators (SQOs) to retrieve data from any object whose class implements the IEnumerable<T> interface. These queries are performed against in-memory data.

  • LINQ to ADO augments SQOs to work against relational data. It is composed of three parts

    • LINQ to SQL : (formerly DLinq) is use to query relational databases such as Microsoft SQL Server.

    • LINQ to DataSet :supports queries by using ADO.NET data sets and data tables.

    • LINQ to Entities : (formerly XLinq) is a Microsoft ORM solution, allowing developers to use Entities to declaratively specify the structure of business objects and use LINQ to query them.

  • LINQ to XML (formerly XLinq) not only augments SQOs but also includes a host of XMLspecific features for XML document creation and queries.

Let we see all the concept given above one by one with an example.

Part 1 : LINQ To Objects

LINQ to Objects can be used with any class that implements the IEnumerable interface. This part will covers the concepts of C# 3.0 new concepts first and then will see how it utilize LINQ,

  1. Object initialization Expressions
  2. Extension Methods
  3. Lamda Expressions
  4. Expression Trees.
  5. Anonymous Types
  6. Implicitly Typed Local Variables

Let’s look at one by one how it works.

1. Object initialization Expressions

Just like an array initializer, an object initialization expression allows us to initialize a new object without calling its constructor and without setting its properties.

           // The standard object creation and initialization
Person p1 = new Person();
p1. FirstName = "Kannan";
p1.LastName = "Arjun";
ObjectDumper.Write(p1);

// The object initialization expression
Person p2 = new Person { FirstName="Kannan", LastName ="Arjun" };
ObjectDumper.Write(p2);


With object initialization expressions you can create an object directly and set its properties using just one statement.

2. Extension Methods

As the name implies, extension methods extend existing .NET types with new methods. Like as obj.ToString(), here ToString() is system function will convert the value as string. In the same way, we can also create our custom function in the name of Extension Method.

For an example 1, by using extension methods with a string, it’s possible to add a new method that converts every space in a string to an underscore(_).

        public static string SpaceToUnderscore(this string source)
{
char[] cArray = source.ToCharArray();
string result = null;
foreach (char c in cArray)
{
if (Char.IsWhiteSpace(c))
result += "_";
else
result += c;
}
return result;
}


Here you define an extension method, SpaceToUnderscore(). To specify an extension method you insert the keyword 'this' before the
first method parameter, which indicates to the compiler the type you want to extend. Note that the method and its class must be static. You can use SpaceToUnderscore() just like any other string method.

Suppose we call this method in the code behinds as given below,

var newstring = "This is kannan test".SpaceToUnderscore() +","+ "Arjun Test".SpaceToUnderscore();

The result of executing this method will return like this,

This_is_kannan_test,Arjun_Test

For an example, to convert a decimal value into string formatted with a specific culture by using extension methods.
In C# 2.0, we can write the custome method for the above case as follows
static class DateFormat
{
public static void Demo()
{
DateTime today = DateTime.Now;
Console.WriteLine(MyLongDateFormat(today));
Console.WriteLine(MyShortDateFormat(today));
}

public static string MyLongDateFormat(DateTime date)
{
return String.Format(date.ToString("U"));
}

public static string MyShortDateFormat(DateTime date)
{
return String.Format(date.ToString("d"));
}
}

After running this sample, we get two different date format as output like this
Thursday, July 03, 2008 1:46:08 AM
7/3/2008

In the above sample we are created two differnet method called MyLongDateFormat() and MyShortDateFormat(). Suppose we need to use this method in some other class, we need to call with full signature.

Now we see how to write the same situation in Extension method.

static class DateFormat
{
public static void Demo()
{
DateTime today = DateTime.Now;
Console.WriteLine(today.MyLongDateFormat());
Console.WriteLine(today.MyShortDateFormat());
}

public static string MyLongDateFormat(this DateTime date)
{
return String.Format(date.ToString("U"));
}

public static string MyShortDateFormat(this DateTime date)
{
return String.Format(date.ToString("d"));
}
}


The output should be the same one what we had in previous sample.


Thursday, July 03, 2008 1:46:08 AM
7/3/2008


Note :

  • Simply by adding the new System.Query namespace, you can use LINQ with any type that implements IEnumerable<t>.
  • If you have an extension method and an instance method with the same signature, priority is given to the instance method.
  • Properties, events, and operators are not extendable

Let we see the rest of the concepts given above in the next post.

    Happy programming!!!