麻烦的LINQ查询/加入

时间:2013-06-18 20:03:22

标签: c# linq linq-to-entities

好的,我甚至不确定从哪里开始。我有四个主要表格。

IPACS_Departments(一对多) - > IPACS_Functions(一对多) - > IPACS_Processes(一对多) - > IPACS_Procedures

我有IPACS_Documents表,其中包含docID的主键。

我有4个查表表。

IPACS_DepartmentDocs - > IPACS_FunctionDocs - > IPACS_ProcesseDocs - > IPACS_ProcedureDocs

这些表格中的每一个都有一个FKIPACS_Document表格docID 他们在FKdepartmentIDfunctionIDprocessID上提及的前四个表中也有procedureID

我需要以某种方式通过LINQ语句将它们连接在一起。

我的部门视图页面。我需要显示当前部门中的每个文档。

例如我们有一个计算机部门。在该部门中有2个功能,在这些功能中有13个进程,在这些进程中有41个程序。

因此,在我的部门视图页面上,我需要显示该部门的所有文档及其功能,以及它的流程和程序。

在我的部门视图页面上,我可以访问departmentID

我100%困惑的是如何使用这9个不同的表格获得所有相关文档?

我希望这是有道理的,因为我的大脑是试图思考这个问题的朋友。

1 个答案:

答案 0 :(得分:1)

我不确定我的模型是否正确,但我认为它遵循这种模式(假设实体框架,后代实体具有映射属性以允许行走的层次结构):

public class Department
{
  [Key]
  public int Id { get; set; }

  public virtual ICollection<Function> Functions { get; set; }

  public virtual ICollection<DepartmentDocument> DepartmentDocuments { get; set; }
}

public class DepartmentDocument
{
  [Key]
  public int Id { get; set; }

  [ForeignKey("Department")]
  public int DeptId { get; set; }

  [ForeignKey("Document")]
  public int DocId { get; set; }

  public virtual Department Department { get; set; }

  public virtual Document Document { get; set; }
}

public class Document
{
  [Key]
  public int Id { get; set; }

  public virtual DepartmentDocument DepartmentDocument { get; set; }

  public virtual FunctionDocument FunctionDocument { get; set; }
}

假设有这样的模型,那么你可以编写以下内容 - 我只包括遍历两个级别,但附加内容只需要一些额外的行SelectMany()用于子元素:

public List<Document> GetDocumentsForDepartment(List<Department> departments)
{
  var docs = new List<Document>();

  foreach (var department in departments)
  {
    foreach (var ddoc in department.DepartmentDocuments)
    {
      docs.Add(ddoc.Document);
    }

    foreach (var fx in department.Functions)
    {
      foreach (var fdoc in fx.FunctionDocuments)
      {
        docs.Add(fdoc.Document);
      }
    }  
  }

  return docs;
}

简化为:

public List<Document> GetDocumentsForDepartment2(List<Department> departments)
{
  var docs = new List<Document>();

  foreach (var department in departments)
  {
    docs.AddRange(department.DepartmentDocuments.Select(ddoc => ddoc.Document));
    docs.AddRange(department.Functions.SelectMany(fx => fx.FunctionDocuments, (fx, fdoc) => fdoc.Document));
  }

  return docs;
} 

这可能没问题,该方案使用多个DB调用(如果您使用EF而不是Linq到Objects)。如果这很糟糕,那么您可能需要在数据库中放置一个视图。

我想不出如何将它写成单个linq查询,所以这可能只是进一步工作的起点。

这是对earlier question的一个非常简单的跟进。当您想要汇总子数据时,您需要SelectMany()