【问题标题】:How to Left Join two Parent-Child tables (i.e. 4 tables)如何左连接两个父子表(即 4 个表)
【发布时间】:2016-03-15 00:23:51
【问题描述】:

我们有以下数据库结构:

我们如何查询属于特定客户和组的所有数据? (使用 Entity Framework 6 编写的示例会很棒。)

我们可以这样做:

var parentChild1 = dbcontext.Parent1.Include(p => p.Child1).Select(p => p.ClientId = clientId).ToList();
var parentChild2 = dbcontext.Parent2.Include(p => p.Child2).Select(p => p.GroupId = groupId).ToList();
// And the manually join the values in parentChild2 with the objects in parentChild1.
// But there has to be a better way than this.

我在想这样的事情;但不知道如何将 child1(s) 与 child2(s) 连接起来:

void GetData(int clientId, int groupId)
{
    var query = (from p1 in dbcontext.Parent1
                 from c1 in dbcontext.Child1
                 where p1.ClientId == clientId && c1.Parent1Id == p1.Id
                 join p2 in dbcontext.Parent2.Where(p2 => p2.GroupId == groupId) 
                     on p1.Id equals p2.Parent1Id into p2groups
                 join c2 in dbcontext.Child2 on c1.Id equals c2.Child2Id into c2groups
                 from p2g in p2groups.DefaultIfEmpty()
                 from c2g in c2groups.DefaultIfEmpty()
                 select new Parent1
                 {
                     Parent2s = p2g,
                     //Child1s = c2g ??? How to wire up child1s with child2s?
                 };
}

【问题讨论】:

  • 我大概可以给你一个sql答案,有帮助吗?
  • 当然,任何帮助将不胜感激。

标签: sql-server c#-4.0 entity-framework-6


【解决方案1】:

以下 sql 语句应返回所有表中属于单个 parent1Id 和 groupId 的所有数据。

SELECT *
FROM Parent1 p1
LEFT JOIN Parent2 p2 ON(p1.Id = p2.Parent1Id AND p2.GroupId = @groupId)
LEFT JOIN Child1 c1 ON(p1.id = c1.Parent1Id)
LEFT JOIN Child2 c2 ON(c1.id = c2.Childe1Id AND p2.id = c2.Parent2Id)
WHERE p1.Id = @Id 

孩子加入是左加入,因为我假设并非所有父母都有孩子,但父母加入是内部加入,因为您需要 groupid 以及 parent1 id。

【讨论】:

  • 按照合理的原则,与 Parent 2 的联接也应该是 LEFT JOIN,因为这是给定关系的基数。 GroupId 可能由于 OUTER JOIN 为空,这与 JOIN 类型的选择无关。出于非常合理的原因,使用SELECT * 是非常不受欢迎的,并且不应该在没有警告的情况下在答案中提出建议。
  • 好吧,select * 只是我的懒惰,我同意不应该使用它。但是我不同意父母之间的联系。我必须说我考虑过对所有连接使用左连接,但后来我发现如果父级没有指定组 id 的记录,则查询不应返回结果,除非 OP 另有指定。
  • OP DID 提供的 ERD 另有说明。它明确指出表之间的关系是1 - *,需要 LEFT JOIN 才能正确。 OP 之所以提出这个问题,很大程度上是因为他正在为 ERD 符号的含义而苦苦挣扎。您发布明显不正确的回复是一种伤害。
  • 我不同意。一对多关系不需要左连接,除非您想要左表中的所有记录,无论是否匹配右表上的记录。选择连接类型的标准不是关系,而是查询的期望输出。
  • 先生,谢谢你们的cmets。但是,在这种特定情况下,您俩都是对的; p1/c2 是安全权限,p2/c2 是安全权限。因此,在创建/编辑用户组时,我们希望返回所有可能的权限以及哪些权限已启用(即转换为权限)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
相关资源
最近更新 更多