LINQ with C# Objects, Collections and Arrays

Language integrated query (LINQ) in .NET 3.5 provides querying capabilities to Object Oriented programming languages like C# or VB.NET. This integration of querying capabilities allows compile time checking of query expressions as well as intellisence support from IDE's using the reflection. Linq allows the developer to write query expressions in his own choice of programming language with out having the necessity to learn different databases and query languages. Linq defines a set of standard query operators to perform SQL operations over the different data sources.

LINQ Architecture

Linq architecture is extensible. Linq includes extensions that provides querying capabilities over different data sources. These extensions are: Linq to Objects: This provides the ability to query IEnumerable<T>-based information sources which include arrays, collections, list of objects. Linq to XML: This provides efficient, easy-to-use, in-memory XML manipulation capabilities to provide XPath/XQuery functionality to the programming languages using simple query operators. Linq to SQL: This gives the ability to access relational data base objects as normal .Net objects. LINQ to SQL integrates SQL based schema definitions to the common language runtime (CLR) type system. This provides strong typing, syntax checking, intellisense over SQL objects, while retaining the expressive power of the relational model and the performance of query evaluation directly in the underlying database.

NET Dataset. ProductsGrid.NET entities. Because the Select operator projecting the complete product object itself. . These are called Standard Query Operators. which is used as the datasource for the GridView object on the aspx page. because of this this the GridView can dynamically generate the column names obtained as the result of the query. The products in the expensiveInStockProducts are added to an ArrayList object list. 2. ArrayList list = new ArrayList(). 4. foreach (var i in expensiveInStockProducts) list. ProductsGrid. Now the GridView showing all the fields of the Product type this is because the select operator projected complete Product object itself. These variables type is implicitly derived from the object types these variables assigned to. 8. The AutoGenerateColumns property of the GridView set to True. whose values are less than 5.Add(i). The above query uses where keyword to find all products that are in stock and cost more than 20. These CLR types are called anonymous types because they don't have a type name. 6. 3. var expensiveInStockProducts = from p in products where p. The variable expensiveInStockProducts is the type of IEnumerable<product> which references to collection of objects of an anonymous type which is type equivalent to Product type. var lowNums = from n in numbers where n < 5 select n.00M select p .00 per unit. The var keyword is used to declare implicitly typed local variables. 1.DataSource = list.AutoGenerateColumns = true.DataBind(). A simple query which used to retrieve objects based on a condition is shown below. The variable products represents strongly typed list of product objects which are initialized from GetProductList() method. 9.UnitPrice > 20. List<Product> products = GetProductList(). ProductsGrid. In the above query from operator used like foreach keyword. 7. The query returns an IEnumerable<T> which references to an in-memory object whose CLR type contains an array of integers. Linq to Entities: Provides the querying capabilities over ADO. The same syntax is used when we are querying over objects. The lownums variable declared by var keyword. where operator used for conditional selection (restriction) and select is used as projection operator to select the fields from the array.UnitsInStock > 0 && p. 0 }. A simple Linq query looks like this: int[] numbers = { 5.Linq to DataSet: Provides the ability to query ADO.

This is mandatory because the select operator is projecting a new type definition.UnitPrice }. Some times we can give a new name to the projected field like below: var productInfos = from p in products select new { p.Using Select Operator to Project individual fields.UnitPrice > 20.ProductName. Price = p.ProductName }. Here we are explicitly using the new keyword to dynamically create an anonymous type. Because the Select operator projecting only ProductID. string ProductName as part of the type definition. . p.ProductID. Now the GridView looks like below with only two columns. ProductName fields of product object. p. the variable expensiveInStockProducts is the type of IEnumerable<anonymous type> references to objects of an anonymous type which contains string ProductID. And the generated type will have Price as the field name instead of UnitPrice as below. var expensiveInStockProducts = from p in products where p.00M select new { p. In the above query the UnitPrice field is renamed with Price.Category.UnitsInStock > 0 && p. These two fields are represented as string fields because both are declared as strings as part of the Product type definition. In the above query.

var sortedProducts = from p in products orderby p. after that the results will be sorted by UnitPrice in descending order like below. If we want to order them in descending order we need to explicitly use the descending keyword followed by the field name on which we want to apply the ordering.Category. The below query outputs the products ordered by the product name field. By default the sorting will be ascending on the field name specified by orderby operator. The above query orders the products by category first. The sorting can be ascending or descending. var sortedProducts = from p in products orderby p. A simple query using compound sorting is shown below.UnitPrice descending select p. . p.ProductName select p. We can apply a compound sort means the sort will be applied on multiple field from left to right.Sorting and Ordering with LINQ The sorting functionality is achieved by using the orderby opertaor.

var categoryCounts = from p in (from c in products .Key).Category. Each item of this enumeration defines a group (IGrouping<string. As in its definition.Grouping in LINQ As like sql we can group the objects using the 'group by' operator in Linq.Add(i. Min operators on the grouped objects the grouped objects must implement the IComparable inorder to do comparision. To retrieve these items.Category) and the products grouped by this common key.Products ) the above statement is used to iterate through the Product collection in each group g in the orderGroups */ } The output of the query orderGroups becomes an enumeration of groups (IEnumerable<IGrouping<string. var orderGroups =from p in products group p by p. ArrayList list = new ArrayList(). /* foreach ( var g in i. Product>). foreach (var i in orderGroups) { list. Normally we will use grouping to get the group count or group max. A simple query which demonstrates grouping is shown below. But if we want to use Max. IGrouping is defined as the combination of the key of the group (p. min of the items. Product>>). we have to enumerate through the group as shown above in the comments. We can get the group count as below.

Category) select new { p.Key. var categoryNames = ( from p in products select p.Distinct(). Union.Count() }. Intersect. The Intersect operator is used to find the objects which are common in both the collections and outputs the same. but the output contains only distinct objects from both the collections.Key. For simplicity the same query can be written using into operator with out using the nested query as shown below. var categoryCounts = from p in products group p by p. The output of the query gives an enumerable object and which can be enumerated to get unique categories. Except) The Distinct operator is used to eliminate duplicate elements from a sequence. ProductCount = p.Category) .Category into g select new { Category = g. Set Operators (Distinct.Count() }. The Union operator is used to combine the objects of two collections. . The output of the above query looks like below. ProductCount = c by c.

Category select new { Category = c.Union(categoriesFirstChars). Linq supports join operations using the joinoperator. And the select operator projecting only the category string and ProductName field of Product. Join in LINQ Joins are the most important function of SQL Operators. "Vegetables". An equijoin can be implemented as below: string[] categories = new string[]{ "Beverages". The output will look like . var categoriesFirstChars = from c in products2 select c.The Except operator is used to find the objects that are present in the first collection but not present in the second collection. p.Except(categoriesFirstChars).ProductName }.ProductName[0]. An example which shows these three operators usage is shown below.Category[0]. "Seafood" }. var IntersectFirstChars = productFirstChars. The join operator performs an inner join of two collections based on matching keys extracted from the elements.Intersect(categoriesFirstChars). The above query joining the categories array with the products collection and the condition for joining is equals means if any category string is matched with category field of the Product object then that pair will be added to join output. var productFirstChars = from p in products select p. var q = from c in categories join p in products on c equals p. "Dairy Products". var ExceptFirstChars = productFirstChars. "Condiments". var uniqueFirstChars = productFirstChars.