正在使用Linq中可能为null的参数

本文关键字:null 参数 Linq | 更新日期: 2023-09-27 18:26:20

我有一个方法要传入两次,开始和结束。用户可以输入一个、两个或不输入。然后,我使用Linq查询数据库,以查找这两次之间的所有记录。当开始和/或结束参数为null时,我将如何处理这些情况。如果两者都不为空,则为

where beginning <= time && time <= end

有没有一种方法可以在不使用if、if else和else语句的情况下写出这些案例?

正在使用Linq中可能为null的参数

检查输入参数是否为null或输入参数是否符合条件。

// from and to are user DateTime? inputs
var filtered = myCollection.Where(x =>
    (from == null || x.Date >= from) &&
    (to == null || x.Date < to));

这适用于所有场景。。。

  • 如果用户未输入日期,则返回所有项目
  • 如果用户输入from,则返回from之后的所有项目
  • 如果用户输入to,则返回to之前的所有项目
  • 如果用户同时输入fromto,则返回fromto之间的所有项目

编辑

这要归功于||操作员短路。在我的回答中,如果未指定可选参数(fromto)(因此为null),则表达式解析为true,甚至不计算第二个条件。但是,如果它们不为null,那么第二个条件也将被检查。

以下是我从以下答案中偷来的C#规范的一个片段:),它解释了(可能比我能解释的更好)短路运算符。

&&||运算符被称为条件逻辑运算符。它们也被称为"短路"逻辑运算符。

操作x && y对应于操作x & y,不同之处在于仅当xtrue时才评估y
操作x || y对应于操作x | y,不同之处在于仅当x不是true时才评估y

操作CCD_ 25被评估为CCD_。换句话说,首先对x进行评估并将其转换为类型bool。然后,如果xtrue,则运算的结果是true。否则,y被评估并转换为类型bool,并且这成为运算的结果。

我做了一个小演示:

将满足您请求的逻辑表达式是:

(!start.HasValue || start < we.Reception) && (we.Reception < end || !end.HasValue)

含义:

(如果开始没有(值小于接收值))

var myTimes = new List<WeddingEvent>()
{
    new WeddingEvent { Id = 1, Reception = DateTime.Now.AddHours(-3) },
    new WeddingEvent { Id = 2, Reception = DateTime.Now.AddHours(-2) },
    new WeddingEvent { Id = 3, Reception = DateTime.Now.AddHours(-1) },
    new WeddingEvent { Id = 4, Reception = DateTime.Now.AddHours(0) },
    new WeddingEvent { Id = 5, Reception = DateTime.Now.AddHours(1) },
    new WeddingEvent { Id = 6, Reception = DateTime.Now.AddHours(2) },
    new WeddingEvent { Id = 7, Reception = DateTime.Now.AddHours(3) },
};
DateTime? start = null; //DateTime.Now.AddHours(0.5);
DateTime? end = DateTime.Now.AddHours(3.5);
var weddingInHalfAnHour = myTimes.Where(we => (!start.HasValue || start < we.Reception) && (we.Reception < end || !end.HasValue));
foreach (var wedding in weddingInHalfAnHour)
{
    Console.WriteLine("Id: {0} ReceptiontTime: {1}", wedding.Id, wedding.Reception);
}