{"id":42193,"date":"2023-09-07T17:31:43","date_gmt":"2023-09-07T17:31:43","guid":{"rendered":"https:\/\/stackify.com\/?p=42193"},"modified":"2024-06-07T08:23:39","modified_gmt":"2024-06-07T08:23:39","slug":"the-linq-join-operator-a-complete-tutorial","status":"publish","type":"post","link":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/","title":{"rendered":"The LINQ Join Operator: A Complete Tutorial"},"content":{"rendered":"\n<p>I think most C# developers would agree that LINQ is an integral part of the experience of writing code with the language. LINQ provides a fluent, intuitive, and consistent way to query data sets. In this post, we&#8217;ll help in your LINQ-mastering quest by covering the LINQ join operator.<\/p>\n\n\n\n<p>We&#8217;ll start the post with a definition of LINQ itself, so we&#8217;re all on the same page. After that, you\u2019ll see an explanation of join operations in LINQ. Then, it&#8217;s time to roll up your sleeves and get practical with our hands-on guide to the join operator.<\/p>\n\n\n\n<p>Let&#8217;s get started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is LINQ?<\/strong><\/h2>\n\n\n\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/linq\/\">LINQ<\/a> stands for Language Integrated Query. It&#8217;s a C# feature that offers a unique and consistent syntax for query datasets, regardless of their origin. The main benefit of LINQ is that you can use the same syntax to query data in memory, from a database, XML files, and so on.<\/p>\n\n\n\n<p>LINQ is available in two different flavors, the query syntax and the method syntax<strong>.<\/strong><\/p>\n\n\n\n<p>The query syntax leverages special keywords to create a syntax that is familiar to anyone who&#8217;s worked with SQL. Here&#8217;s an example that queries a sequence of numbers, filtering the ones greater than 5:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int&#91;] numbers = { 2, 8, 4, 9, 3, 6, 1, 7, 5 };\n<p>var largerThanFive = from num in numbers&nbsp;&nbsp;&nbsp;&nbsp;where num &gt; 5&nbsp;&nbsp;&nbsp;&nbsp;select num;<\/p><\/code><\/pre>\n\n\n\n<p>The method syntax allows you to use extension methods to perform the same query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int&#91;] numbers = { 2, 8, 4, 9, 3, 6, 1, 7, 5 };\nvar largerThanFive = numbers.Where(x =&gt; x &gt; 5);\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"200\" src=\"https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp3.png\" alt=\"\" class=\"wp-image-43336\" srcset=\"https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp3.png 1000w, https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp3-300x60.webp 300w, https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp3-150x30.webp 150w, https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp3-768x154.webp 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is The LINQ Join Operator?<\/strong><\/h2>\n\n\n\n<p>When working with data, a common scenario is having two data sources that you want to combine based on some criteria. For instance, you might have a Books table and an Authors table in your database, with a one-to-many relationship between them\u2014i.e., an author can author many books, but each book has only one author. If you need to compile a list of books containing their author&#8217;s name, you&#8217;d need to perform a join in order to match each line from the Books table to its counterpart in the Authors table.<\/p>\n\n\n\n<p>A join in LINQ is essentially the same: an operation where you can merge two collections according to some criteria you define.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The LINQ Join Operator in Practice<\/strong><\/h2>\n\n\n\n<p>Examples always make things clearer. So, let&#8217;s see how to use the join operator in practice.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Starting With a Problem<\/strong><\/h3>\n\n\n\n<p>Let&#8217;s say you have an e-commerce application with some data on categories:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Id<\/strong><\/td><td><strong>Name<\/strong><\/td><\/tr><tr><td>1<\/td><td>Electronics<\/td><\/tr><tr><td>4<\/td><td>Toys<\/td><\/tr><tr><td>5<\/td><td>Stationery<\/td><\/tr><tr><td>7<\/td><td>Books<\/td><\/tr><tr><td>10<\/td><td>Clothes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Okay, now let&#8217;s have some products:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Id<\/strong><\/td><td><strong>Name<\/strong><\/td><td><strong>Category_Id<\/strong><\/td><\/tr><tr><td>1<\/td><td>Amazon Kindle<\/td><td>1<\/td><\/tr><tr><td>2<\/td><td>Refactoring<\/td><td>7<\/td><\/tr><tr><td>3<\/td><td>C# in Depth<\/td><td>7<\/td><\/tr><tr><td>4<\/td><td>Legal Pad 50 sheets<\/td><td>5<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>You can see where this is leading, right? The next thing you&#8217;d want to do is to produce a single collection, having the list of products and the names of the categories they belong to. In other words, a view like this:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Id<\/strong><\/td><td><strong>Name<\/strong><\/td><td><strong>Category<\/strong><\/td><\/tr><tr><td>1<\/td><td>Amazon Kindle<\/td><td>Electronics<\/td><\/tr><tr><td>2<\/td><td>Refactoring<\/td><td>Books<\/td><\/tr><tr><td>3<\/td><td>C# in Depth<\/td><td>Books<\/td><\/tr><tr><td>4<\/td><td>Legal Pad 50 sheets<\/td><td>Stationery<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Solving The Problem: Performing a LINQ Inner Join<\/strong><\/h3>\n\n\n\n<p>What would that operation look like in code? First of all, we need code to represent our categories and products. Thanks to C#&#8217;s record feature, two lines of code suffice for that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public record Product(int Id, string Name, int CategoryId);\npublic record Category(int Id, string Name);<\/code><\/pre>\n\n\n\n<p>Now, let&#8217;s have a list of each type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var categories = new List&lt;Category&gt;\n{\n    new Category(1, \"Electronics\"),\n    new Category(4, \"Toys\"),\n    new Category(5, \"Stationery\"),\n    new Category(7, \"Books\"),\n    new Category(10, \"Clothes\")\n};\n\nvar products = new List&lt;Product&gt;\n{\n    new Product(1, \"Amazon Kindle\", 1),\n    new Product(2, \"Refactoring\", 7),\n    new Product(3, \"C# In Depth\", 7),\n    new Product(4, \"Legal Pad 50 Sheets\", 5),\n    new Product(5, \"Surgical Gloves\", 12)\n};<\/code><\/pre>\n\n\n\n<p>As you can see, the list of products has an additional product (surgical gloves) whose category id doesn&#8217;t match any of the available categories. Keep this in mind; it&#8217;ll be relevant in a moment.<\/p>\n\n\n\n<p>Now, let&#8217;s write code to perform this join. I&#8217;ll show the code in one go and then explain it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var query =\n    from p in products\n    join c in categories\n    on p.CategoryId equals c.Id\n    select new\n    {\n        Id = p.Id,\n        Name = p.Name,\n        Category = c.Name\n    };\n\nforeach (var line in query)\n{\n    Console.WriteLine(line);\n}<\/code><\/pre>\n\n\n\n<p>Now, the explanation:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>from p in products<\/strong> -&gt; we&#8217;re defining the origin of one of our data sources<\/li>\n\n\n\n<li><strong>join c in categories<\/strong> -&gt; Here, we&#8217;re saying that we want to join the previous collection with this one<\/li>\n\n\n\n<li><strong>on p.CategoryId equals c.Id<\/strong> -&gt; This is the condition for the join: the CategoryId on each product should match the Id of a category<\/li>\n\n\n\n<li><strong>select new&#8230; <\/strong>-&gt;<strong> <\/strong>Here, we&#8217;re leveraging C#&#8217;s anonymous objects feature to create a new object on the fly, which has the properties we want<\/li>\n<\/ul>\n\n\n\n<p>The result of this query is an IEnumerable of our anonymous object. We then iterate through each item of this collection, displaying it on the console. This is the result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{ Id = 1, Name = Amazon Kindle, Category = Electronics }\n{ Id = 2, Name = Refactoring, Category = Books }\n{ Id = 3, Name = C# In Depth, Category = Books }\n{ Id = 4, Name = Legal Pad 50 Sheets, Category = Stationery }<\/code><\/pre>\n\n\n\n<p>Those of you who remember your databases will notice that the LINQ join we performed is the equivalent of an inner join in SQL. In other words, only items that have a match are returned. In SQL, the equivalent query would look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT p.Id, p.Name, c.Name AS Category\nFROM products AS p\nJOIN categories AS c ON p.CategoryId = c.Id<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Performing a LINQ Outer Join<\/strong><\/h3>\n\n\n\n<p>What if you wanted to perform the equivalent of a SQL outer join? That is, you want to retrieve all products, even the ones that don&#8217;t match any category. How to go about that?<\/p>\n\n\n\n<p>Here&#8217;s the updated query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var query =\n    from p in products\n    join c in categories\n    on p.CategoryId equals c.Id into joinedCategories\n    from c in joinedCategories.DefaultIfEmpty()\n    select new\n    {\n        Id = p.Id,\n        Name = p.Name,\n        Category = c?.Name\n    };<\/code><\/pre>\n\n\n\n<p>&nbsp;&nbsp;It looks similar, but there are two differences:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>on p.CategoryId equals c.Id into joinedCategories <\/strong>-&gt; here, after joining products with categories, we send the result, as a grouped sequence, to the <strong>joinedCategories<\/strong> range variable<\/li>\n\n\n\n<li><strong>from c in joinedCategories.DefaultIfEmpty()<\/strong> -&gt; Then, we retrieve items from the groupedSequence, using the DefaultIfEmpty() method to return the default value when no matches are found<\/li>\n\n\n\n<li><strong>Category = c?.Name<\/strong> -&gt; Finally, when assigning the category name to the Category property on our anonymous object, we have to use the null-conditional operator in order to avoid a null-reference exception (since the default value for Category is null because it&#8217;s a reference type.)<\/li>\n<\/ul>\n\n\n\n<p>The result is now different:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{ Id = 1, Name = Amazon Kindle, Category = Electronics }\n{ Id = 2, Name = Refactoring, Category = Books }\n{ Id = 3, Name = C# In Depth, Category = Books }\n{ Id = 4, Name = Legal Pad 50 Sheets, Category = Stationery }\n{ Id = 5, Name = Surgical Gloves, Category =  }<\/code><\/pre>\n\n\n\n<p>As you can see, the &#8220;Surgical Gloves&#8221; product now appears, even if it doesn&#8217;t have a matching category.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LINQ Inner Join With Where Condition<\/strong><\/h3>\n\n\n\n<p>Performing a join with a where clause is quite easy. In this example, we&#8217;ll perform an inner join, filtering only the products whose id are equal to or greater than 3:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var query =\n    from p in products\n    where p.Id >= 3\n    join c in categories\n    on p.CategoryId equals c.Id\n    select new\n    {\n        Id = p.Id,\n        Name = p.Name,\n        Category = c.Name\n    };\n\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"200\" src=\"https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp4.png\" alt=\"\" class=\"wp-image-43338\" srcset=\"https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp4.png 1000w, https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp4-300x60.webp 300w, https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp4-150x30.webp 150w, https:\/\/stackify.com\/wp-content\/uploads\/2024\/03\/sp4-768x154.webp 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LINQ Inner Join With Multiple Conditions<\/strong><\/h3>\n\n\n\n<p>If you want to use multiple conditions within your join, you can simply use more than one where clause. Let&#8217;s update our query once again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var query =\n    from p in products\n    join c in categories\n    on p.CategoryId equals c.Id\n    where p.Id &gt;= 3\n    where c.Name.EndsWith('s')\n    select new\n    {\n        Id = p.Id,\n        Name = p.Name,\n        Category = c.Name\n    };<\/code><\/pre>\n\n\n\n<p>Here, we&#8217;re filtering only categories whose names end with the letter s.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>LINQ Join With Composite Key<\/strong><\/h3>\n\n\n\n<p>Up until now, all of our examples have used single keys to perform the matching. You can also use composite keys\u2014that is, more than one value\u2014for the matching.<\/p>\n\n\n\n<p>Suppose both our Product and Category classes gained a new property called Status, which is an enum that can vary between three states: Pending, Active, and Archived. Now, the Status property also needs to be used for the match.<\/p>\n\n\n\n<p>All of our products are active, but not all of the categories:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var categories = new List&lt;Category&gt;\n{\n    new Category(1, \"Electronics\", Status.Active),\n    new Category(4, \"Toys\", Status.Active),\n    new Category(5, \"Stationery\", Status.Archived),\n    new Category(7, \"Books\", Status.Pending),\n    new Category(10, \"Clothes\", Status.Active)\n};\n\nvar products = new List&lt;Product&gt;\n{\n    new Product(1, \"Amazon Kindle\", 1,  Status.Active),\n    new Product(2, \"Refactoring\", 7,  Status.Active),\n    new Product(3, \"C# In Depth\", 7,  Status.Active),\n    new Product(4, \"Legal Pad 50 Sheets\", 5,  Status.Active),\n    new Product(5, \"Surgical Gloves\", 12,  Status.Active)\n};<\/code><\/pre>\n\n\n\n<p>This is what our updated query looks like now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var query =\n    from p in products\n    join c in categories\n    on new { Id = p.CategoryId, Status = p.Status }\n    equals new { Id = c.Id, Status = c.Status }\n    select new\n    {\n        Id = p.Id,\n        Name = p.Name,\n        Category = c.Name\n    };<\/code><\/pre>\n\n\n\n<p>It&#8217;s not much more complicated than before. The difference is that now, we use an anonymous object to perform the comparison using both the id and the status properties.<\/p>\n\n\n\n<p>A single result is displayed from this query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{ Id = 1, Name = Amazon Kindle, Category = Electronics }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>As we&#8217;ve seen, LINQ is an essential part of working with C#. You can leverage LINQ in many different scenarios, from working with data in memory to XML to SQL. You can use LINQ in ORMs such as<a href=\"https:\/\/stackify.com\/entity-framework-core-nhibernate\/\"> NHibernate and Entity Framework.<\/a><\/p>\n\n\n\n<p>Teams that wish to make their LINQ experiences even better can use the tools at their disposal. For instance,<a href=\"https:\/\/stackify.com\/prefix\/\"> Stackify&#8217;s Prefix<\/a> and<a href=\"https:\/\/stackify.com\/retrace-code-profiling\/\"> Retrace<\/a> offer powerful capabilities of tracing, profiling, and centralizing logging that helps teams inspect their code to find opportunities for performance improvements, which includes LINQ queries.<\/p>\n\n\n\n<p><em>This post was written by <\/em><em>Carlos Schults. <\/em><a href=\"https:\/\/carlosschults.net\"><em>Carlos<\/em><\/a><em> is a consultant and software engineer with experience in desktop, web, and mobile development. Though his primary language is C#, he has experience with a number of languages and platforms. His main interests include automated testing, version control, and code quality.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets<\/p>\n","protected":false},"author":198,"featured_media":42196,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7],"tags":[236,235,237],"class_list":["post-42193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-c-features","tag-linq-join","tag-linq-join-operator"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v25.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>The LINQ Join Operator: A Complete Tutorial - Stackify<\/title>\n<meta name=\"description\" content=\"LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The LINQ Join Operator: A Complete Tutorial - Stackify\" \/>\n<meta property=\"og:description\" content=\"LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets\" \/>\n<meta property=\"og:url\" content=\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Stackify\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Stackify\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-07T17:31:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-07T08:23:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png\" \/>\n\t<meta property=\"og:image:width\" content=\"640\" \/>\n\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"HitSubscribe\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@stackify\" \/>\n<meta name=\"twitter:site\" content=\"@stackify\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"HitSubscribe\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\"},\"author\":{\"name\":\"HitSubscribe\",\"@id\":\"https:\/\/stackify.com\/#\/schema\/person\/698c56e2a9a802d4c154b8bea22f9402\"},\"headline\":\"The LINQ Join Operator: A Complete Tutorial\",\"datePublished\":\"2023-09-07T17:31:43+00:00\",\"dateModified\":\"2024-06-07T08:23:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\"},\"wordCount\":1262,\"publisher\":{\"@id\":\"https:\/\/stackify.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png\",\"keywords\":[\"C# features\",\"LINQ join\",\"LINQ join operator\"],\"articleSection\":[\"Developer Tips, Tricks &amp; Resources\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\",\"url\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\",\"name\":\"The LINQ Join Operator: A Complete Tutorial - Stackify\",\"isPartOf\":{\"@id\":\"https:\/\/stackify.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png\",\"datePublished\":\"2023-09-07T17:31:43+00:00\",\"dateModified\":\"2024-06-07T08:23:39+00:00\",\"description\":\"LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage\",\"url\":\"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png\",\"contentUrl\":\"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png\",\"width\":640,\"height\":360},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/stackify.com\/#website\",\"url\":\"https:\/\/stackify.com\/\",\"name\":\"Stackify\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/stackify.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/stackify.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/stackify.com\/#organization\",\"name\":\"Stackify\",\"url\":\"https:\/\/stackify.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/stackify.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/stackify.com\/wp-content\/uploads\/2024\/05\/logo-1.png\",\"contentUrl\":\"https:\/\/stackify.com\/wp-content\/uploads\/2024\/05\/logo-1.png\",\"width\":1377,\"height\":430,\"caption\":\"Stackify\"},\"image\":{\"@id\":\"https:\/\/stackify.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Stackify\/\",\"https:\/\/x.com\/stackify\",\"https:\/\/www.instagram.com\/stackify\/\",\"https:\/\/www.linkedin.com\/company\/2596184\",\"https:\/\/www.youtube.com\/stackify\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/stackify.com\/#\/schema\/person\/698c56e2a9a802d4c154b8bea22f9402\",\"name\":\"HitSubscribe\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/stackify.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2edcf404a46a088bccf2c1643e051382?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2edcf404a46a088bccf2c1643e051382?s=96&d=mm&r=g\",\"caption\":\"HitSubscribe\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"The LINQ Join Operator: A Complete Tutorial - Stackify","description":"LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"The LINQ Join Operator: A Complete Tutorial - Stackify","og_description":"LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets","og_url":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/","og_site_name":"Stackify","article_publisher":"https:\/\/www.facebook.com\/Stackify\/","article_published_time":"2023-09-07T17:31:43+00:00","article_modified_time":"2024-06-07T08:23:39+00:00","og_image":[{"width":640,"height":360,"url":"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png","type":"image\/png"}],"author":"HitSubscribe","twitter_card":"summary_large_image","twitter_creator":"@stackify","twitter_site":"@stackify","twitter_misc":{"Written by":"HitSubscribe","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#article","isPartOf":{"@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/"},"author":{"name":"HitSubscribe","@id":"https:\/\/stackify.com\/#\/schema\/person\/698c56e2a9a802d4c154b8bea22f9402"},"headline":"The LINQ Join Operator: A Complete Tutorial","datePublished":"2023-09-07T17:31:43+00:00","dateModified":"2024-06-07T08:23:39+00:00","mainEntityOfPage":{"@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/"},"wordCount":1262,"publisher":{"@id":"https:\/\/stackify.com\/#organization"},"image":{"@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png","keywords":["C# features","LINQ join","LINQ join operator"],"articleSection":["Developer Tips, Tricks &amp; Resources"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/","url":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/","name":"The LINQ Join Operator: A Complete Tutorial - Stackify","isPartOf":{"@id":"https:\/\/stackify.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png","datePublished":"2023-09-07T17:31:43+00:00","dateModified":"2024-06-07T08:23:39+00:00","description":"LINQ provides a fluent, intuitive and consistent way to query data sets. See how LINQ join operations simplify queries on multiple data sets","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/stackify.com\/the-linq-join-operator-a-complete-tutorial\/#primaryimage","url":"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png","contentUrl":"https:\/\/stackify.com\/wp-content\/uploads\/2023\/09\/The-LINQ-Join-Operator-A-Complete-Tutorial.png","width":640,"height":360},{"@type":"WebSite","@id":"https:\/\/stackify.com\/#website","url":"https:\/\/stackify.com\/","name":"Stackify","description":"","publisher":{"@id":"https:\/\/stackify.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/stackify.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/stackify.com\/#organization","name":"Stackify","url":"https:\/\/stackify.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/stackify.com\/#\/schema\/logo\/image\/","url":"https:\/\/stackify.com\/wp-content\/uploads\/2024\/05\/logo-1.png","contentUrl":"https:\/\/stackify.com\/wp-content\/uploads\/2024\/05\/logo-1.png","width":1377,"height":430,"caption":"Stackify"},"image":{"@id":"https:\/\/stackify.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Stackify\/","https:\/\/x.com\/stackify","https:\/\/www.instagram.com\/stackify\/","https:\/\/www.linkedin.com\/company\/2596184","https:\/\/www.youtube.com\/stackify"]},{"@type":"Person","@id":"https:\/\/stackify.com\/#\/schema\/person\/698c56e2a9a802d4c154b8bea22f9402","name":"HitSubscribe","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/stackify.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/2edcf404a46a088bccf2c1643e051382?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2edcf404a46a088bccf2c1643e051382?s=96&d=mm&r=g","caption":"HitSubscribe"}}]}},"_links":{"self":[{"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/posts\/42193"}],"collection":[{"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/users\/198"}],"replies":[{"embeddable":true,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/comments?post=42193"}],"version-history":[{"count":6,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/posts\/42193\/revisions"}],"predecessor-version":[{"id":43339,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/posts\/42193\/revisions\/43339"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/media\/42196"}],"wp:attachment":[{"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/media?parent=42193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/categories?post=42193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stackify.com\/wp-json\/wp\/v2\/tags?post=42193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}