实体框架需要更长的时间才能在同一个上下文中首次使用响应

时间:2015-03-19 15:14:23

标签: entity-framework

我遇到EF的问题,第一次查询需要很长时间。我认为查询本身需要很长时间。所以,我用了

context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

查看正在发送的查询。它只需要1毫秒,但从开放连接到关闭连接,需要18秒。以下是调试消息中的消息。

**Opened connection at 3/19/2015 9:25:49 PM +06:30 
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[ItemId] AS [ItemId], 
    [Extent1].[SerialNumber] AS [SerialNumber], 
    [Extent1].[SimNumber] AS [SimNumber], 
    [Extent1].[ItemStatusId] AS [ItemStatusId], 
    [Extent1].[StoreId] AS [StoreId]
    FROM [dbo].[ItemDetail] AS [Extent1]
-- Executing at 3/19/2015 9:25:49 PM +06:30
-- Completed in 1 ms with result: SqlDataReader
    Closed connection at 3/19/2015 9:26:07 PM +06:30**

在同一个上下文中,发送了与前一个类似的另一个查询。从开放到关闭连接仅用了1秒钟。

**Opened connection at 3/19/2015 9:26:10 PM +06:30

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[ItemId] AS [ItemId], 
    [Extent1].[SerialNumber] AS [SerialNumber], 
    [Extent1].[SimNumber] AS [SimNumber], 
    [Extent1].[ItemStatusId] AS [ItemStatusId], 
    [Extent1].[StoreId] AS [StoreId]
    FROM  [dbo].[ItemDetail] AS [Extent1]
    INNER JOIN [dbo].[Item] AS [Extent2] ON [Extent1].[ItemId] = [Extent2].[Id]
    WHERE ([Extent1].[ItemStatusId] = @p__linq__0) AND ([Extent2].[CategoryId] = @p__linq__1) AND ([Extent1].[StoreId] = @p__linq__2)


-- p__linq__0: '1' (Type = Int32, IsNullable = false)

-- p__linq__1: '2' (Type = Int32, IsNullable = false)

-- p__linq__2: '1' (Type = Int32, IsNullable = false)

-- Executing at 3/19/2015 9:26:10 PM +06:30

-- Completed in 1 ms with result: SqlDataReader

Closed connection at 3/19/2015 9:26:11 PM +06:30**

为什么第一个查询需要更长时间才能关闭连接?

我知道第一个查询通常需要时间,因为加载了元数据。但是这与开放连接和执行查询非常接近是不同的,在获得结果之后,在第一个查询中关闭连接需要很长时间。

1 个答案:

答案 0 :(得分:0)

在不知道代码的更多细节的情况下,我能想到的唯一因素是如何处理LINQ查询。特别是可以导致连接保持相对较长时间的一件事是枚举LINQ查询并在每次迭代中执行一些耗时的过程:

var details = from d in ItemDetail
              where ...
              select new { ... }

foreach (var detail in details)
{
    // DbDataReader reads a record on each iteration
    SomeLengthyProcess(detail);
}
// Connection is closed after the last iteration.

这是一个示例输出(省略一些不相关的细节)

Opened connection at 09:48:33

SELECT statement

-- Executing at 09:48:33

-- Completed in 14 ms with result: SqlDataReader

Record1
Record2
Record3
Record4
Record5

Closed connection at 09:48:37

这表明语句本身是在" no time"中执行的,但是读者需要另外4秒才能生成每条记录。

更快地关闭连接的方法是:

foreach (var detail in details.ToList())

首先构建内存列表然后迭代它。在这种情况下,连接在"完成"之后立即关闭。记录线。