【问题标题】:Linq -- Join on joined table's primary keyLinq -- 加入连接表的主键
【发布时间】:2017-07-26 15:40:30
【问题描述】:

来自 T-SQL,我正在尝试在示例 ASP.Net mvc (c#) 程序中使用基本数据集。

我有三个表格,如下图(链接)所示:

  1. 集合(PK IdCollection)
  2. Sprint(PK IdSprint、FK IdCollection)
  3. DeployDocuments(PK IdDeployDocuments,FK IdSprint)

在我的 asp.net mvc 控制器中,我想将这个简单查询的 linq 等效数据集传递给视图:

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;

我一辈子都想不出该怎么做! 一旦我尝试在 linq 中创建第二个联接(更不用说左联接)。

我以前只是在使用:

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

但我也需要所有项目的总和(deployDocuments),所以现在我正试图像这样讨价还价:

        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

但是一旦我进入第二个加入它就会抛出错误,我应该阅读的 linq 是否存在限制?我应该采取完全不同的方法来解决这个问题吗?或者我应该只是 GTFO 并参加更多关于 C# 的课程

【问题讨论】:

  • 为什么不能为此使用存储过程?你确定要使用 LINQ 吗?
  • 我绝对可以使用存储过程,我还没有学会如何在 asp.net mvc 中使用存储过程,但我相信我可以学得足够快。这是在 linq 中执行的“复杂”查询吗? 编辑: 我想我的看法有点偏差,因为我不习惯为少于 10-15 行的查询创建存储过程,最好的做法是使用 SP t 一个“基本”查询?
  • 使用LEFT JOIN 会变得复杂。我不是说它不可行,只是以你的水平,使用存储过程可能更容易。
  • 应该很容易使用导航属性,如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() }

标签: c# sql sql-server asp.net-mvc linq


【解决方案1】:

Linq 左连接看起来与 SQL 左连接有点不同,所以它可能有点混乱。 This SO answer 展示了一种编写 Linq 左连接的简单方法。 .DefaultIfEmpty() 使第二个连接成为左连接。

这是我想出的:

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() };

【讨论】:

  • 谢谢,感谢您抽出宝贵时间回答这个问题!它看起来像预期的那样工作;然而,它让我意识到我有点过头了,可能应该只是退后一步,然后再学习一些关于 c# 和一般数据集的课程。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 2011-04-29
相关资源
最近更新 更多