c# - 缓冲区缓存清理时出现“超时已过期”错误

标签 c# .net winforms linq sql-server-2005

我将首先总结我的问题,然后提供大量细节和我已经尝试过的方法。

总结:

我有一个内部 winform 应用程序,它使用 Linq 2 Sql 连接到本地 SQL Express 数据库。每个用户都有自己的数据库,数据库通过合并复制与中央数据库保持同步。所有数据库都是 SQL 2005(sp2or3)。我们已经使用这个应用程序 5 个多月了,但最近我们的用户收到 Timeout expired。操作完成前超时时间已过或服务器未响应。

详细:

奇怪的是,他们在两个不同的位置(2 种不同的 LINQ 方法)得到了它,并且只在给定的时间段内第一次触发(~5 分钟) .

一种 LINQ 方法是提取与 FK ID 匹配的所有记录,然后操纵它们以形成 TreeView 的层次结构 View 。第二个是提取与 FK ID 匹配的所有记录并将它们转储到 DataGridView 中。我唯一能找到的与 2 的共同点是第一个是 IEnumerable,第二个从 IQueryable -> IEnumerable -> DataTable... 转换自身。

我在 Profiler 中查看了查询,它们“看起来”很正常。它们不是很复杂的查询。他们只从一张表中拉回 10 - 90 条记录。

任何想法、建议、暗示都将不胜感激。我对此束手无策....


public IList<CaseNoteTreeItem> GetTreeViewDataAsList(int personID)
{
    var myContext = MatrixDataContext.Create();

    var caseNotesTree =
        from cn in myContext.tblCaseNotes
        where cn.PersonID == personID
        orderby cn.ContactDate descending,
            cn.InsertDate descending
        select new CaseNoteTreeItem
        {
            CaseNoteID = cn.CaseNoteID,
            NoteContactDate = Convert.ToDateTime(cn.ContactDate).
                ToShortDateString(),
            ParentNoteID = cn.ParentNote,
            InsertUser = cn.InsertUser,
            ContactDetailsPreview = cn.ContactDetails.Substring(0, 75)
        };

    return caseNotesTree.ToList<CaseNoteTreeItem>();            
}

还有这个

public static DataTable GetAllCNotes(int personID)
{
    using (var context = MatrixDataContext.Create())
    {
        var caseNotes =
            from cn in context.tblCaseNotes
            where cn.PersonID == personID
            orderby cn.ContactDate
            select new
            {
                cn.ContactDate,
                cn.ContactDetails,
                cn.TimeSpentUnits,
                cn.IsCaseLog,
                cn.IsPreEnrollment,
                cn.PresentAtContact,
                cn.InsertDate,
                cn.InsertUser,
                cn.CaseNoteID,
                cn.ParentNote
            };

        return caseNotes.ToList().CopyLinqToDataTable();
    }
}

编辑以显示生成的 SQL

这是GetTreeViewAsList(int personID)

SELECT [t0].[CaseNoteID], [t0].[ParentNote] AS [ParentNoteID], CONVERT(DateTime,[t0].[ContactDate]) AS [value], [t0].[InsertUser], SUBSTRING([t0].[ContactDetails], 0 + 1, 75) AS [ContactDetailsPreview]
FROM [dbo].[tblCaseNotes] AS [t0]
WHERE [t0].[PersonID] = 123456
ORDER BY [t0].[ContactDate] DESC, [t0].[InsertDate] DESC

这是 GetALLCaseNotes(int personID)

SELECT [t0].[ContactDate], [t0].[ContactDetails], [t0].[TimeSpentUnits], [t0].[IsCaseLog], [t0].[IsPreEnrollment], [t0].[PresentAtContact], [t0].[InsertDate], [t0].[InsertUser], [t0].[CaseNoteID], [t0].[ParentNote]
FROM [dbo].[tblCaseNotes] AS [t0]
WHERE [t0].[PersonID] = 123456
ORDER BY [t0].[ContactDate]

最佳答案

PersonId 上缺少索引意味着这两个问题查询都需要进行全表扫描。当数据不在缓冲区中时,这意味着大量 I/O,这解释了为什么您会注意到它,特别是在给定时间段内它们第一次触发时。

添加以下索引应该可以解决它。

CREATE NONCLUSTERED INDEX ix_tblCaseNotes_PersonID ON tblCaseNotes (PersonID)

关于c# - 缓冲区缓存清理时出现“超时已过期”错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2951024/

相关文章:

c# - 如果我之后直接使用 `Response.Flush()` ,那么 `Response.End()` 有意义吗?

c# - 通过开始屏幕颜色更改磁贴背景颜色

c# - 当类是通用的时找不到 Web API Controller

c# - 当类的名称是根元素时,Newtonsoft json 不会反序列化

c# - 资源文件未编译成 DLL

c# - 如何导入文件名为 "improper"的 CSV 文件?

.net - 如何判断连接是否按流量计费?

c# - 如果反序列化时 json 中不存在,则保留旧值

c#在SplitContainer中使用TreeView控件改变内容

C# 备份和恢复剪贴板