Используя таблицу, которая мне пригодилась (поскольку вы не указали схемы), используя 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();
Это будет один выше и один ниже. Однако обратите внимание, что возвращение нулевого значения здесь не происходит, когда вы не находите строку выше или ниже, оно просто исключает такие результаты. Если вы действительно заботитесь, вы можете взять 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]