2011-05-04 28 views
3

我有三個表,Entity,Period和Result。 Entity和Period之間有1:1映射,Period和Result之間有1:1映射。我如何優化這個Linq查詢來刪除不必要的SELECT Count(*)

這是LINQ查詢:

int id = 100; 
DateTime start = DateTime.Now; 

from p in db.Periods 
where p.Entity.ObjectId == id && p.Start == start 
select new { Period = p, Results = p.Results }) 

這是生成的SQL的相關部分:

SELECT [t0].[EntityId], [t2].[PeriodId], [t2].[Value], (
    SELECT COUNT(*) 
    FROM [dbo].[Result] AS [t3] 
    WHERE [t3].[PeriodId] = [t0].[Id] 
    ) AS [value2] 

FROM [dbo].[Period] AS [t0] 
INNER JOIN [dbo].[Entity] AS [t1] ON [t1].[Id] = [t0].[EntityId] 
LEFT OUTER JOIN [dbo].[Result] AS [t2] ON [t2].[PeriodId] = [t0].[Id] 
WHERE ([t1].[ObjectId] = 100) AND ([t0].[Start] = '2010-02-01 00:00:00') 

哪裏SELECT COUNT(*)從快到了,我怎麼能擺脫它?我不需要對每個「期間」的「結果」進行計數,它會將查詢速度降低一個數量級。

+2

我認爲計數實際上是這樣它可以將您的笛卡兒積結果變成一個多結果。因此,如果您有許多期間有很多結果,它會知道每個期間結果的數量,當它轉換結果時。 – Phill 2011-05-04 03:14:48

+1

我猜這種行爲的原因是LinqToSql試圖準備一些嵌套集合的行由於某些原因。嘗試使用數據上下文的「DeferredLoadingEnabled」屬性或任何其他關於** Lazy Loading **的方法。無論如何,LinqToSql現在不支持。切換到EF。 – Genius 2011-05-04 06:38:37

+5

@Genius - 「LinqToSql現在不支持?」它是最新版本的.NET 4.0,它仍然受支持。也許你不支持它,但那是另一回事! :-P – 2011-05-04 07:03:47

回答

1

考慮使用Context.LoadOptions並指定Period到LoadWith(p => p.Results)以便無需投影到匿名類型中即可加載結果的句點。