1. Group Join A group join is similar to using the GroupBy operator, although the syntax and semantics differ slightly. A group join uses the Join operator and the Into keyword to group the results of the join. The following query returns all categories and uses a group join to create a group of related products for each category. var product = from category in dbml.Categories join prod in dbml.Products on category equals prod.Category into CategoryProduct select new { categoryName = category.CategoryName, ProductCout = CategoryProduct.Count(), Products = CategoryProduct }; foreach (var P in product) { Console.WriteLine("Category name : {0} \n Product Count : {1} ", P.categoryName, P.ProductCout); foreach (var Cate in P.Products) { Console.WriteLine("Product name : {0} ", Cate.ProductName); } }
Note that to use a group join in Visual Basic you must use the syntax Group Join instead of join, as is used in C#. In both cases, the results are grouped via the Into keyword. As in the GroupBy operator example, C# can group the data into a group of any name whereas in Visual Basic you must use the name Group. The results of the group join are identical to the nested query's. Namely, the result is a sequence with one element for each category, regardless of whether the category has any associated products. Each element has a "sub-sequence" that contains the products associated with that category (if any). Refer to the first screen shot in this article for a visual representation of these results.
2. Inner Join An inner join queries two sequences. For each pair of elements examined, the pair is returned as output if the pair match on some specified criteria. Otherwise the pair is omitted from the results. Let's look at an example. The following query syntax queries two sequences - FauxNorthwind.Data.Categories and FauxNorthwind.Data.Products - joining together the Product and Category objects with matching categories. The Join operator generates a sequence whose elements have two properties: category and product. This result is projected via the Select operator into an anonymous type that returns the just the CategoryName property from the category object along with the entire product object. // C# var CategoriesAndProducts = from category in FauxNorthwind.Data.Categories join product in FauxNorthwind.Data.Products on category equals product.Category select new { category.CategoryName, product }; ' VB Dim CategoriesAndProducts = _ From category In FauxNorthwind.Data.Categories _ Join product In FauxNorthwind.Data.Products _ On category Equals product.Category _ Select _ CategoryName = category.CategoryName, _ product The above query syntax is quite similar to SQL's JOIN syntax. Here we query "from" the FauxNorthwind.Data.Categories "table" and join with theFauxNorthwind.Data.Products "table" where the Category objects line up. If it helps, you can envision the above LINQ query as the following SQL statement: SELECT Categories.CategoryName, Products.* FROM Categories INNER JOIN Products ON Categories.CategoryId = Products.CategoryId The LINQ query generates a sequence with 15 elements, one for each product in the "database." Each item in the resulting sequence includes the category's name and all fields from the Product object. The following screen shot shows a GridView that displays the CategoryName property in the first column and the product's ProductName andUnitPrice properties in the second column.
' VB Dim CategoriesAndProducts = _ From category In FauxNorthwind.Data.Categories _ Group Join product In FauxNorthwind.Data.Products _ On category Equals product.Category Into Group _ From product In Group.DefaultIfEmpty() _ Select _ CategoryName = category.CategoryName, _ product Note that there is both a group join and an additional From operator that queries the resulting group join sub-sequence, which are the products that match the category. TheDefaultIfEmpty() extension method is used here to return null if there are no items in the sub-sequence (i.e., if there are no matching products for the category). The resulting output of the above query is a sequence with 16 elements. One element for each product plus one element for the category that has no products associated with it (Meat/Produce). The screen shot below shows this data when bound to a GridView.
4. Cross Joins
A cross join is the Cartesian product between the two entities performing the join. In other words, the cross join outputs an element for every single possible combination of elements in the two inputs. When doing a cross join on two sequences with sizes A and B, the resulting cross join has A x B results. A cross join in LINQ is accomplished by having two From operators that specify the two sequences to combine, as the following query syntax illustrates: // C# var CategoriesAndProducts = from category in FauxNorthwind.Data.Categories from product in FauxNorthwind.Data.Products select new { category.CategoryName, product.ProductName, product.UnitPrice }; ' VB Dim CategoriesAndProducts = _ From category In FauxNorthwind.Data.Categories _ From product In FauxNorthwind.Data.Products _ Select _ category.CategoryName, _ product.ProductName, _ product.UnitPrice The above query generates a resulting sequence with 90 elements and contains all of the category/product combinations, even if the combinations aren't valid. For instance, the resulting sequence includes the pairing of category and product Meat/Produce and Chai, even though Chai product belongs to the Beverages category and the Meat/Produce category has no associated products.