简体   繁体   English

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

[英]C#, ASP.Net Core and Linq: dealing with null dates

I am having trouble craft a multi join query in Visual Studio 2019, C#, ASP.Net core. 我在Visual Studio 2019,C#,ASP.Net核心中编写多联接查询时遇到麻烦。

I have two tables: 我有两个表:

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
)

Paired events like login/logout are put into the event table. 成对的事件(如登录/注销)被放入事件表中。 A trigger on INSERTs to the events table handles the management of the sessions table. events表的INSERT上的触发器处理sessions表的管理。 For this question assume that the sessions table could look like: 对于这个问题,假设会话表如下所示:

 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

In SSMS I can write the query I want as: 在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

I have tried this in C# as: 我已经在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();

I am told that "Left operand of '??' 有人告诉我,“'?”的左操作数 should be a reference or nullable type". 应该是引用或可为空的类型”。 The problem is that the underlying field ("eventDate" in events) can not be null. 问题在于基础字段(事件中的“ eventDate”)不能为null。 How do I deal with this? 我该如何处理?

The eventDate will never be null since, as you said, it's not nullable. 如您所说,由于eventDate不可为空,因此它永远不会为null。 The nullable object that you would want to check for is the EndEvents (since you are doing a left join against that entity). 您要检查的可为空对象是EndEvents (因为您正在对该实体执行左连接)。 You could use the null-conditional operator syntax here: 您可以在此处使用空条件运算符语法:

EndEvents?.eventDate ?? DateTime.Now

This will fall into the right hand side ( DateTime.Now ) in the case that EndEvents is null. 如果EndEvents为null,它将落在右侧( DateTime.Now )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM