C#,ASP.Net Core和Linq:处理空日期

时间:2019-04-22 20:19:59

标签: c# asp.net-core

我无法在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
)

已配对的事件(例如登录/注销)被放入事件表中。 events表的INSERT上的触发器处理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”)不能为null。我该如何处理?

1 个答案:

答案 0 :(得分:2)

eventDate永远不会为空,因为正如您所说,它不可为空。您要检查的可为空的对象是EndEvents(因为您正在对该实体执行左联接)。您可以在此处使用null-conditional operator语法:

EndEvents?.eventDate ?? DateTime.Now

DateTime.Now为空的情况下,这将落在右侧(EndEvents)上。