C #, ASP.Net Core и Linq: работа с нулевыми датами - PullRequest
0 голосов
/ 22 апреля 2019

У меня возникают проблемы при создании запроса на множественное объединение в Visual Studio 2019, C #, ядре ASP.Net.

У меня есть две таблицы:

sessions(
    id          int primary key,
    start_id    int not null,   // foreign key to "start event" event.id
    end_id      int             // foreign key to "end event" event.id
)

events(
    id  int primary key,
    username    varchar(32) not null,
    deviceName  varchar(64) not null,
    eventName   varchar(8) not null,
    eventDate   datetime not null
)

Парные события, такие как вход / выход из системыпомещаются в таблицу событий.Триггер на INSERT для таблицы events обрабатывает управление таблицей sessions.Для этого вопроса предположим, что таблица сессий может выглядеть следующим образом:

 id | start_id | end_id
----+----------+--------
  1 | 1        | null
  2 | 2        | 3

events:
 id | userName | deviceName | eventName | eventDate
----+----------+------------+-----------+-----------
  1 | alice    | moose      | login     | 2019-03-11 14:02:54
  2 | bob      | juno       | login     | 2019-03-11 15:11:08
  3 | bob      | juno       | logout    | 2019-03-11 17:18:22

В SSMS я могу написать запрос, который я хочу, как:

SELECT
    sessions.id,
    StartEvents.userName,
    StartEvents.deviceName,
    StartEvents.eventDate as startDate,
    ISNULL(EndEvents.eventDate, GETDATE()) as endDate
FROM sessions
JOIN events StartEvents
    ON sessions.start_id = StartEvents.id
LEFT JOIN events EndEvents
    ON sessions.end_id = EndEvents.id
WHERE StartEvents.eventDate >= @myStart
      AND ISNULL(EndEvents.eventDate, GETDATE()) <= @myEnd

Я пробовал это в C # как:

var result = (
    from sessions in db.Sessions
    join StartEvents in db.Events
        on sessions.Start_id equals StartEvents.Id
    join EndEventsTmp in db.Events
        on sessions.End_id equals EndEventsTmp.Id into EndEventsTmp2
    from EndEvents in EndEventsTmp2.DefaultIfEmpty()
    where StartEvents.Machine.Trim().ToUpper().Equals(machine.Trim().ToUpper())
          & StartEvents.eventDate >= myStart
          & (EndEvents.eventDate ?? DateTime.Now) <= myEnd
    orderby StartEvents.Date
    select new UserTrackingToFullCalendar {
        Id = StartEvents.Id,
        User = StartEvents.userName,
        Device = StartEvents.deviceName.ToUpper(),
        Start = StartEvents.eventDate,
        End = EndEvents.eventDate ?? DateTime.Now
    }
    ).ToList();

Мне сказали, что «левый операнд» ??должен быть ссылочным или обнуляемым типом ".Проблема в том, что базовое поле («eventDate» в событиях) не может быть пустым.Как мне с этим справиться?

1 Ответ

2 голосов
/ 22 апреля 2019

eventDate никогда не будет нулевым, поскольку, как вы сказали, он не может быть равен нулю. Обнуляемый объект, который вы хотели бы проверить, это EndEvents (поскольку вы делаете левое соединение с этой сущностью). Вы можете использовать синтаксис для условного оператора *1003* здесь:

EndEvents?.eventDate ?? DateTime.Now

Это попадет в правую часть (DateTime.Now) в случае, если EndEvents равно нулю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...