0

Coming from T-SQL, I am attempting to work with a basic dataset in an example ASP.Net mvc (c#) program.

I have three tables as shown in the photo(linked) below:

  1. Collections (PK IdCollection)
  2. Sprints (PK IdSprint, FK IdCollection)
  3. DeployDocuments (PK IdDeployDocuments, FK IdSprint)

Table relationship diagram

In my asp.net mvc controller, I would like to pass the linq equivalent dataset of this simple query to the view:

SELECT 
c.TxCollectionName
,s.SprintNumber
,COUNT(dd.IdDeployDocument) [NumProjects]
FROM Collections AS c
JOIN Sprints AS s
    ON s.IdCollection = c.IdCollection
LEFT JOIN DeployDocuments AS dd
    ON dd.IdSprint = s.IdSprint
GROUP BY 
c.TxCollectionName
, s.SprintNumber;

I cannot, for the life of me, figure out how to do this! As soon as I try to create a second join in linq (let alone a left join).

I was previously just using:

var CollectionSprints = db.Collections.Include(d => d.Sprints)

But I need the Sum of all projects (deployDocuments) as well, so now I'm trying to haggle together a query like so:

        var query = from Collections in db.Collections
                join Sprints in db.Sprints on Collections.IdCollection equals Sprints.IdCollection
                join DeployDocuments in db.DeployDocuments on DeployDocuments.IdSprint equals Sprints.IdSprint

but as soon as I get down to the second join it's throwing off errors, is there a limitation of linq I should read up on? Is there a completely different approach that I should take to solve this problem? Or should I just GTFO and take more courses on C#

juharr
  • 31,741
  • 4
  • 58
  • 93
  • Why can't you use a stored procedure for this? Are you determined to use LINQ? – SS_DBA Jul 26 '17 at 15:44
  • I can absolutely use a stored procedure with this, I have not yet learned how to use stored procedures with asp.net mvc but I'm sure I can learn quickly enough. Is this a "complex" query to perform in linq? **edit:** I guess my perception is a bit skewed, because I'm not used to creating stored procedures for queries less than 10-15 lines long, is it best practice to use SP's for everything that isn't a "basic" query? – Daniel Kelley Jul 26 '17 at 15:48
  • With the `LEFT JOIN` is can get complicated. I'm not saying it's not doable, just with your level, it might be easier to go with a stored procedure. – SS_DBA Jul 26 '17 at 15:50
  • Should be easily done with navigation properties like `from c in db.Collections from s in c.Sprints from dd in s.DeployDocuments.DefaultIfEmpty() group dd.IdDeployDocument by {c.TxCollectionName,s.SprintNumber} into grp select new { grp.Key.TxCollectionName, grp.Key.SprintNumber, NumProjects = grp.Count() }` – juharr Jul 26 '17 at 16:00

1 Answers1

1

The Linq left join looks a bit different from an SQL left join, so it can be a little confusing. This SO answer shows an easy way to write Linq left-joins. The .DefaultIfEmpty() makes the second join a left join.

Here's what I came up with:

var result = (
    from c in Collections
    from s in Sprints.Where(s => s.IdCollection == c.IdCollection)
    from dd in DeployDocuments.Where(dd => dd.IdSprint == s.IdSprint).DefaultIfEmpty()
    select new { c, s, dd } )
.GroupBy(g => new { g.c.TxCollectionName, g.s.SprintNumber })
.Select(s => new { s.Key.TxCollectionName, s.Key.SprintNumber, NumProjects = s.Count() };
user2023861
  • 8,030
  • 9
  • 57
  • 86
  • Thank you, I appreciate you taking the time to answers this! It looks to work as expected; however, it makes me realize that I'm in a bit over my head and should probably just backpedal and take a few more courses on c# and datasets in general. Thanks again! – Daniel Kelley Jul 26 '17 at 16:16