我对LINQ缺乏了解

Jam*_*son 1 c# linq lambda

好吧,我有几个表链接在一起.

Departments (k = departmentID)
Functions (k = functionID, fk = departmentID)
Processes (k = processID, fk = functionID)
Procedures (k = procedureID, fk = processID)
Run Code Online (Sandbox Code Playgroud)

因此,当我试图想出一些linq时,他们都设置了他们的关系,我遇到了一些奇怪的事情.

以下代码将返回给我

Departments.Select(s => s.Functions)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是当试图进一步扩展该查询时,它不会让我.我希望能够加入所有上述表格,并根据需要从中提取信息.

Departments.Select(s => s.Functions.Process.Procedure) // Errors out
Run Code Online (Sandbox Code Playgroud)

我还可以做更多的事情:

Functions.Select(s => s.Processes)
Run Code Online (Sandbox Code Playgroud)

它似乎会为两个表但不超过2个表做?我错过了什么吗?

sma*_*man 5

这就是事情.在DepartmentsFunctions关系是一对多的.所以当你刚写的时候

 Departments
Run Code Online (Sandbox Code Playgroud)

你有一组Department对象.由于每个Department对象都有自己的Function对象集合,因此:

 Departments.Select(departmentObject => departmentObject.Functions)
Run Code Online (Sandbox Code Playgroud)

为您提供Function对象集合的集合.

如果要将所有这些聚合在一起,则必须使用不同的方法

 Departments.SelectMany(departmentObject => departmentObject.Functions)
Run Code Online (Sandbox Code Playgroud)

其中说"获取Function对象集合的集合并将它们组合成一个大的Function对象集合"

你要做的是:

Departments.Select(departmentObject => departmentObject .Functions.Process.Procedure)
Run Code Online (Sandbox Code Playgroud)

但是,这不可能有效,因为您要求Function为其Process属性提供一组对象.但是,Function对象集合没有Process属性.一个Function对象,本身有一个Process属性.那么,你真正想要做的是:

 Departments
     .SelectMany(departmentObject => departmentObject.Functions)
     .Select(functionObject => functionObject.Process.Procedure)
Run Code Online (Sandbox Code Playgroud)

它基本上转换为"获取Function对象集合的集合并将它们组合成一个大的Function对象集合.然后,获取每个对象的Procedure属性的Process属性Function".

因此,您应该期待的只是由与任何部门相关联的任何功能的过程执行的过程的集合.

请注意,如果部门的功能,功能的过程或过程的过程中存在任何重叠,那么您可能会在最终结果中获得一些重复的过程.如果这不是你想要的,那么你可以使用该Distinct()方法删除重复项,你应该在有重叠的任何地方这样做,但不应该有重复.只需添加Distinct()到查询的末尾即可获得相同的结果,但如果沿途杀死重复项,您将获得更好的性能.因此,实际上,您的查询可能看起来像下面和上一个查询之间的内容,具体取决于有多少重叠以及您想要多少重复:

 Departments
     .SelectMany(departmentObject => departmentObject.Functions)
     .Distinct()
     .Select(functionObject => functionObject.Process)
     .Distinct()
     .Select(processObject => processObject.Procedure)
     .Distinct();
Run Code Online (Sandbox Code Playgroud)