Blogger news

Blogger templates

Friday, February 4, 2011

Projection LINQ Operator- Select and Select Many

Projection Operator- Select and Select Many

Select Operator
"Select" LINQ operator selects element(element means each value in a collection) or elements from a sequence (collection). "Select" returns IEnumerable. “Select” have two overloads. I will explain the structure of “Select” as below,

Click image to expand




Let us see the overload that I pointed.

Here “this IEnumerable<TResult> Source” means that “Select” is an extension method extend IEnumerable type.

“Func<Associate,TResult>” is the method parameter of “Select” method. This Func can point to any method which has one input parameter of type Associate and returns TResult( TResult can be any type). If difficult to follow what I mean please read my post on delegate and Func.
So I can point the method,

public string SelectData(Associate associate)
{
return associate.FirstName;
}

with the Func in Select method. So when select method asking for Func I can pass below method as it matches the signature of Func in select method. Now I can write “Select” as

IEnumerable<string> selectAssociate = associates.Select(SelectData);
foreach (var associate in selectAssociate)
{
Console.WriteLine(associate);
}
Console.ReadKey();

The whole program looks like,

using System;
using System.Collections.Generic;
using System.Linq;

namespace funcexamples
{
class MyFuncClass
{
static void Main(string[] args)
{
List<Associate> associates = new List<Associate>
{ new Associate {AssociateId = 100,FirstName="Sreelas",LastName="Sreekumar",Location="Cochin"},
new Associate{AssociateId=101,FirstName="Serosh",LastName="Vikraman",Location="Trivandrum"},
new Associate{AssociateId=102,FirstName="Mohandas",LastName="PK",Location="Banglore"}
};

IEnumerable<string> selectAssociate = associates.Select(SelectData);
foreach (var associate in selectAssociate)
{
Console.WriteLine(associate);
}
Console.ReadKey();
}

public static string SelectData(Associate associate)
{
return associate.FirstName;
}
}

class Associate
{
public int AssociateId { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public string Location { get; set; }
}
}

Next I will explain the same implementation using Lambda expression.

Lambda expression for the above is,




In the above image why i have given IEnumerable<string> to store data is because we are returning FirstName only from the collection and it's type is string. if you want to return more than one value from the Associate collection with “Select” it should be,

So select operator is just to Project data from a collection.


SelectMany Operator


SelectMany is another projection operator in LINQ. It is nothing but simply join one one more collection and fetch data from each collection. I will explain with an example. Consider a structure “Associate” and “Project” collection and i want to get data from both table. Please find the full code below and will explain step by step,
SelectMany have this many oveload as shown,



In the previous example i wrote lambda expression for third overload that i pointed. i will explain that lambda,



var joinedResult = associates.Where(a => a.ProjectId == 1).SelectMany(associate => projects,
(associate, project) =>
new
{
associate.AssociateId,
project.ProjectId,
associate.FirstName,
associate.LastName,
project.ProjectName
}).Where(a => a.ProjectId == 1);




Leave the "Where" in the query as i already discussed about "Where" in previous blog. Let see "SelectMany". First parameter to this "SelectMany" is "Func<TSource, IEnumerable<TCollection>>" which means this Func accept one parameter of type “TSource”(can be any type) and returning IEnumerable<TCollection>, means collection of any type. So we implemented it as,
associate => projects

here “ associate” is of type “Associate” and “projects” is a collection that we declared outside (Please check the screen shot of the whole program above). Here “associate” is input type and “projects” is the return collection (from this only second parameter Func get the input types) .
Now the second parameter,
Func<TSource, TCollection, TResult> resultSelector, which means this Func have two input parameters(TSource, TCollection) and return TResult so I implemented it as,

(associate, project) => new
{
associate.AssociateId,
project.ProjectId,
associate.FirstName,
associate.LastName,
project.ProjectName
}
Compiler expecting the first parameter in this Func of type “Associate” and second parameter a collection of type “Project” so here associate is of type “Associate” and project is of type “Project” (TCollection means type of collection). Right side of lambda is returning data.
This is the meaning of that overload. If you get this then you can write the remaining overloads.

No comments:

Post a Comment