Использование таблицы я имел под рукой (как вы не представили схемы), используя 5 в качестве заполнителя для фактической переменной в LINQPad:
var pabove = (from p in PolicyStatuses
where p.PolicyStatusID >= 5
orderby p.PolicyStatusID ascending
select p).Take(2);
var pbelow = (from p in PolicyStatuses
where p.PolicyStatusID <= 5
orderby p.PolicyStatusID descending
select p).Take(2);
pabove.Union(pbelow).Dump();
Это будет захватить один сверху и один снизу. Обратите внимание, однако, что возврат null не происходит здесь, когда вы не находите строку выше или ниже, она просто исключает такие результаты. Если вы действительно заботитесь, вы можете взять счет pabove и pbelow, чтобы определить, была ли найдена такая запись.
Результат (очевидно, снова из моей схемы):
IOrderedQueryable<PolicyStatus> (3 items)
PolicyStatusID Status RecordCreated
4
Unknown
8/26/2007 11:06:11 PM
5
Expired
8/26/2007 11:06:11 PM
6
Cancelled
8/26/2007 11:06:11 PM
Обратите внимание, что 4, 5 и 6 были найдены. Это имеет преимущество перед загрузкой всей таблицы, а затем подбор результатов рядом с тем, который вы хотите. Используя Take (2), только 3 записи должны проходить через провод от вашего SQL-сервера к вашему веб-серверу. Если ваша таблица достаточно маленькая, просто попросите таблицу сортировать и фильтруйте то, что вам нужно.
Вот SQL производится LINQ (некоторые поля опущены):
SELECT [t2].[PolicyStatusID], [t2].[Status], [t2].[RecordCreated]
FROM (
SELECT TOP (2) [t0].[PolicyStatusID], [t0].[Status], [t0].[RecordCreated]
FROM [PolicyStatus] AS [t0]
WHERE [t0].[PolicyStatusID] >= @p0
ORDER BY [t0].[PolicyStatusID]
UNION
SELECT TOP (2) [t1].[PolicyStatusID], [t1].[Status], [t1].[RecordCreated]
FROM [PolicyStatus] AS [t1]
WHERE [t1].[PolicyStatusID] <= @p1
ORDER BY [t1].[PolicyStatusID] DESC
) AS [t2]
Можете ли вы показать пример кода? Это было бы полезно. Благодарю. – Thomas