2015-04-01 190 views
0

我想繼續從我的Projects表中獲取所有或至少一些列,這些列與我的TimeTrackings表有一對多的關係。使用EF SelectMany拼合列表

當我創建查詢時,只有所有的子(TimeTracking實體)字段出來,並且只是父項(項目表)的ID。

如何使用SelectMany實現有效連接以扁平列表獲取所有列或至少從兩個實體中指定特定列。

下面,是我使用的EF查詢:

Customers.SelectMany(p => p.Projects).Where (p => p.Quote != null).SelectMany (t => t.TimeTrackings).Where (t => t.Notes != null) 

下面是通過LINQPad生成的SQL查詢。 注意只有ProjectID而不是該實體的其他關聯列出來。

SELECT 
    [Extent2].[TimeTrackingID] AS [TimeTrackingID], 
    [Extent2].[ProjectID] AS [ProjectID], 
    [Extent2].[StartDate] AS [StartDate], 
    [Extent2].[EndDate] AS [EndDate], 
    [Extent2].[Notes] AS [Notes], 
    [Extent2].[CreatedDate] AS [CreatedDate], 
    [Extent2].[UpdatedDate] AS [UpdatedDate] 
    FROM [dbo].[Projects] AS [Extent1] 
    INNER JOIN [dbo].[TimeTrackings] AS [Extent2] ON [Extent1].[ProjectID] = [Extent2].[ProjectID] 
    WHERE ([Extent1].[Quote] IS NOT NULL) AND ([Extent2].[Notes] IS NOT NULL) 

下面是查詢的輸出: enter image description here

回答

1

你可以形成的LINQ如下

from c in Customers 
from p in c.Projects 
from t in p.TimeTrackings 
where p.Quotes != null 
where t.Notes != null 
select new { Project = p, TimeTrack = t } 

另外,可以改變select語句到項目的各個屬性

select new { ProjectId = p.Id, TimeTrackId = t.Id, Anything = p.Anything } 
+0

這看起來像使用QUERY語法的更合乎邏輯的分辨率,其中INNER JOINS被生成以獲得期望的列。 – sagesky36 2015-04-01 14:42:11

1

可能是你正在尋找的是Select方法做列的投影:

Customers.SelectMany(p => p.Projects) 
     .Where (p => p.Quote != null) 
     .SelectMany (t => t.TimeTrackings) 
     .Where (t => t.Notes != null) 
     .Select(x => new { x.ProjectID, x.Project.Name, x.Project.CustomerId }); 
+0

這個解決方案也將工作,但我想,爲什麼我使用方法語法來創建連接,而不是上面的查詢語法。兩者都可以工作,但使用QUERY語法來執行連接而不是METHOD語法似乎更自然。如果是這種情況,爲什麼我需要使用SelectMany操作?上面的QUERY語法比SelectMany更能完成INNER JOIN。 SelectMany甚至不包括客戶實體的任何屬性。如果是這樣的話,我需要使用SelectMany方法的具體情況是什麼? – sagesky36 2015-04-01 14:47:50