Linq группировка по обнуляемой дате и использованию этого в качестве критерия
Я борюсь с обнуляемым столбцом даты и времени [DateInsp] в приложении ASP.NET, которое использует SubSonic3, Linq, MS SQL Server 2005.
У меня все это работало, когда столбец datetime [DateInsp] не допускал пустых значений. Новое требование заставило меня установить столбец [DateInsp], чтобы разрешить нулевые значения, и теперь я изо всех сил пытаюсь заставить эту часть функциональности работать должным образом снова.
Проблема 1: Мне нужно сначала отобразить выпадающий список 7 самых последних дат проверки для данного инспектора (это сгруппированный список 7 самых последних дат для инспектора). Вот TSQL, который мне нужно преобразовать в синтаксис Linq:
declare @InspectorID varchar(5)
set @InspectorID = 'GPA'
select top 7 convert(nvarchar(30), [DateInsp], 101) InspectedDate
from [dbo].[IncomingInspection]
group by [InspectorID], convert(nvarchar(30), [DateInsp], 101)
having [InspectorID] = @InspectorID
order by convert(nvarchar(30), [DateInsp], 101) desc
Если я не могу правильно выполнить эту работу с помощью Linq, НО я могу / могу создать хранимый процесс, чтобы вернуть список дат и выбросить его в выпадающий список. Справедливо. Я боролся с синтаксисом Linq, поэтому любая помощь в этой области очень ценится.
Проблема 2: Мне нужно использовать выбранную дату в раскрывающемся списке, указанном выше, чтобы получить правильные записи для этого инспектора и правильную дату. Опять же, это поле даты и времени, которое можно обнулять, и это является для меня настоящим камнем преткновения.
Вот оригинальный синтаксис Linq, который выполнил требование, прежде чем мне пришлось изменить поле datetime, чтобы разрешить Nulls:
Dim query = (From i In db.IncomingInspections _
Where i.InspectorID = User.Identity.Name _
Group By Key = New With {i.DateInsp} Into Group _
Order By Key.DateInsp Descending _
Select Key = New With {.DateInsp = Key.DateInsp.ToShortDateString}).Take(7)
Это приложение написано на VB.NET и использует синтаксис Linq, из-за которого у меня болит голова. Если вы можете предложить синтаксис C# для этого, я могу перевести его на VB.NET сам.
РЕДАКТИРОВАТЬ:
По какой-то причине я не могу использовать свойство.Value; Я получаю: член 'Значение' не поддерживается
Я получаю: "Неверный синтаксис рядом с '<'." если я попытаюсь добавить сравнение даты к предложению where.
КОНЕЦ РЕДАКТИРОВАНИЯ
Большое спасибо,
мистифицировать
2 ответа
Я решил использовать две хранимые процедуры для решения этой проблемы, исключив необходимость использования синтаксиса Linq:
Вот TSQL, который я использовал, чтобы получить список последних 7 дат проверки (только с частью даты в поле даты и времени):
select top 7 convert(nvarchar(30), [DateInsp], 101) InspectedDate
from [dbo].[IncomingInspection]
group by [InspectorID], convert(nvarchar(30), [DateInsp], 101)
having [InspectorID] = @InspectorID
order by convert(nvarchar(30), [DateInsp], 101) desc
Вот tsql, который я использовал для получения отфильтрованного списка записей проверок для инспектора и даты проверки, выбранной в раскрывающемся списке (используя только часть даты в утверждении критериев):
select [ID]
,[InspectorID]
,[DateInsp]
-- (more fields here)
from [dbo].[IncomingInspection]
where [InspectorID] = @InspectorID and DATEADD(dd, 0, DATEDIFF(dd, 0, [DateInsp])) = DATEADD(dd, 0, DATEDIFF(dd, 0, @DateFilter))
Иногда мне просто нужно идти с работами, а не с новыми и блестящими. Иногда я боролся с простейшими вещами в Linq, и я думаю, что это связано и с тем, что Linq для меня новичок, и я бьюсь над синтаксисом VB.NET, особенно когда объединяю его с Linq.
Извините, что отвечаю на C#, но вот моя интерпретация ваших запросов:
Проблема № 1.
Вы используете наличие в вопросе, а также конвертировать datetime в строки. Я не видел необходимости ни в одной из этих операций.
string inspectorId = "GPA";
List<DateTime?> someDates = db.IncomingInspection
.Where(insp => insp.InspectorId == inspectorId)
.Select(insp => insp.InspectedDate)
.Distinct()
.OrderByDescending(d => d)
.Take(7)
.ToList();
Задача № 2.
Есть два случая: либо у вас есть ноль от пользователя, либо у вас есть значение. Это просто написать запрос для каждого случая. Так просто, что я чувствую, что неправильно понял намерение здесь.
DateTime? selectedDate = control.SelectedValue;
List<IncomingInspection> someRecords = null;
if (selectedDate.HasValue())
{
DateTime selectedDateValue = selectedDate.Value;
someRecords = db.IncomingInspection
.Where(insp => insp.InspectorId == inspectorId)
.Where(insp => insp.InspectedDate == selectedDateValue)
.ToList();
}
else
{
someRecords = db.IncomingInspection
.Where(insp => insp.InspectorId == inspectorId)
.Where(insp => insp.InspectedDate == null)
.ToList();
}