Сначала я подведу итог своей проблемы, а затем предложу подробные сведения и то, что уже попробовал.
Резюме:
У меня есть внутреннее приложение winform, которое использует Linq 2 Sql для подключения к локальной базе данных SQL Express. У каждого пользователя есть своя БД, и она остается синхронизированной посредством репликации слиянием с центральной БД. Все БД являются SQL 2005 (sp2or3). Мы используем это приложение уже более 5 месяцев, но в последнее время наши пользователи получают Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Детальнее:
Странно то, что они получают это в двух разных местах ( 2 разных метода LINQ ) и только в первый раз, когда они запускаются за определенный период времени ( ~ 5 минут ).
Один метод LINQ извлекает все записи, которые соответствуют идентификатору FK, а затем управляет ими, чтобы сформировать представление Heirarchy для TreeView. Второй - извлечение всех записей, соответствующих идентификатору FK, и сброс их в DataGridView. Единственное, что я могу найти общего с этими двумя, это то, что первый является IEnumerable, а второй преобразуется из IQueryable -> IEnumerable -> DataTable ...
Я посмотрел на запросы в Профилировщике, и они «казались» нормальными. Это не очень сложные запросы. Они извлекают только 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]