2

我正在使用实体框架(代码优先)构建一个 ASP.Net 应用程序,并且我已经实现了一个存储库模式,就像这个示例中的那样

我的数据库中只有两个表。一个叫Sensor一个叫MeasurePoint(只包含TimeStampand Value)。一个传感器可以有多个测量点。目前我有 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)

执行只需约 200 毫秒,因此时间花在了其他地方。

我在 Visual Studio Profiler 的帮助下分析了代码,发现导致延迟的调用是

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

所以我想这与延迟加载有关。我必须忍受这样的表现还是我可以做出改进?是否是按时间排序导致性能下降,如果是,我有什么选择?

更新: 我已经更新了代码以显示sensor来自哪里。

4

2 回答 2

2

What that will do is load the entire children collection into memory and then perform the .First() linq query against the loaded (appx 3000) children.

If you just want the most recent, use this instead:

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

于 2012-10-01T12:52:28.273 回答
1

如果这是它正在运行的查询,它会将所有 3000 个点加载到传感器的内存中。尝试直接在 DbContext 上运行查询,而不是使用导航属性,看看性能差异是什么。您的开销可能来自您不需要加载的 2999 个点。

于 2012-10-01T12:51:22.253 回答