title: Left outer join using LINQ -- understanding the code
body: <p>I would be grateful if someone could explain the meaning of the term <code>into</code> while using <strong>LINQ</strong>. In general, I am trying to understand how to make <strong>INNER JOIN</strong>, <strong>LEFT OUTER JOIN</strong> etc. in <strong>C#</strong>.</p>
  
  <p>I have the main table <code>Students</code> that stores a few foreign ID keys which then are substituted by their names when running a query. The names are read from look up tables such as <code>Marks</code>, <code>SoftwareVersions</code>, <code>Departments</code> etc. All fields are required but <code>MarkID</code>. The query I tried to build in <strong>LINQ</strong> is this:</p>
  
  <pre><code>SELECT * FROM dbo.Students
  INNER JOIN dbo.Departments ON dbo.Students.DepartmentID=dbo.Departments.DepartmentID
  INNER JOIN dbo.SoftwareVersions ON dbo.Students.SoftwareVersionID=dbo.SoftwareVersions.SoftwareVersionID
  INNER JOIN dbo.Statuses ON dbo.Students.StatusID=dbo.Statuses.StatusID
  LEFT JOIN dbo.Marks ON dbo.Students.MarkID=dbo.Marks.MarkID
  WHERE dbo.Students.DepartmentID=17;
  </code></pre>
  
  <p>I somehow managed to get the code below worked after reading plenty of articles and watching some videos but I don't feel like I have a complete understanding of the code. The bits that confuse me are in 5th line ending with <code>into</code> and then in the very next line beginning with <code>from m ...</code>. I'm confused what <code>into</code> does and and what really happens in <code>from m ...</code>. And this is the code in LINQ:</p>
  
  <pre><code>var result = from st in dbContext.Students where st.DepartmentID == 17
               join d in dbContext.Departments on st.DepartmentID equals d.DepartmentID
               join sv in dbContext.SoftwareVersions on st.SoftwareVersionID equals sv.SoftwareVersionID
               join stat in dbContext.Statuses on st.StatusID equals stat.StatusID
               join m in dbContext.Marks on st.MarkID equals m.MarkID into marksGroup
               from m in marksGroup.DefaultIfEmpty()
               select new
               {
                   student = st.StudentName,
                   department = p.DepartmentName,
                   software = sv.SoftwareVersionName,
                   status = st.StatusName,
                   marked = m != null ? m.MarkName : "-- Not marked --"
               };
  </code></pre>