我遇到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**
为什么第一个查询需要更长时间才能关闭连接?
我知道第一个查询通常需要时间,因为加载了元数据。但是这与开放连接和执行查询非常接近是不同的,在获得结果之后,在第一个查询中关闭连接需要很长时间。
答案 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())
首先构建内存列表然后迭代它。在这种情况下,连接在"完成"之后立即关闭。记录线。