2012-10-01 183 views
2

我正在用實體框架(代碼優先)構建ASP.Net應用程序,並且實施了一個存儲庫模式like the one in this example使用實體框架加載子實體時性能不佳

我的數據庫中只有兩個表。一個叫做Sensor,另一個叫MeasurePoint(僅包含TimeStampValue)。傳感器可以有多個測量點。目前我有5個傳感器和大約15000個測量點(每個傳感器大約有3000個點)。

在我的MVC控制器之一,我執行以下行(以獲取最新的傳感器MeasurePoint)

DbSet<Sensor> dbSet = context.Set<Sensor>(); 
var sensor = dbSet.Find(sensorId); 
var point = sensor.MeasurePoints.OrderByDescending(measurePoint => measurePoint.TimeStamp).First(); 

此調用需要〜1秒,以執行感覺就像對我很重要。通話結果如下SQL查詢

SELECT 
[Extent1].[MeasurePointId] AS [MeasurePointId], 
[Extent1].[Value] AS [Value], 
[Extent1].[TimeStamp] AS [TimeStamp], 
[Extent1].[Sensor_SensorId] AS [Sensor_SensorId] 
FROM [dbo].[MeasurePoint] AS [Extent1] 
WHERE ([Extent1].[Sensor_SensorId] IS NOT NULL) AND ([Extent1].[Sensor_SensorId] = @EntityKeyValue1) 

這隻需要〜200ms執行,所以時間花在其他地方。

我異形的代碼與Visual Studio探查器的幫助下,發現引起延遲呼叫

System.Data.Objects.Internal.LazyLoadBehavior.<>c_DisplayClass7`2.<GetInterceptorDelegate>b_1(!0,!1) 

所以我猜它是與延遲加載。我是否需要像這樣的表演生活,還是我可以改進?是否按時間順序導致性能下降,如果是這樣,我有什麼選擇?

更新: 我更新了代碼以顯示sensor來自哪裏。

+0

難道只有第一個調用的執行時間? – Dennis

+0

不,不幸的是不是 – Joel

+0

什麼類型的「傳感器」對象是?它是'DbContext'嗎? – Dennis

回答

2

這樣做會將整個子集合加載到內存中,然後對加載的(appx 3000)子級執行.First()linq查詢。

如果你只是想最近的,而不是使用:

context.MeasurePoints.OrderByDescending(measurePoint => measurePoint.TimeStamp).First();

+0

謝謝。這要快得多。 – Joel

1

如果這是它正在運行的查詢,它會將所有3000點加載到傳感器的內存中。嘗試直接在您的DbContext上運行查詢,而不是使用導航屬性,並查看性能差異。你的開銷可能來自你不需要加載的2999點。