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

时间:2015-12-11 00:08:22

标签: c# linq

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

where beginning <= time && time <= end

有没有办法在不使用if,if else,else语句的情况下编写这些案例?

2 个答案:

答案 0 :(得分:1)

检查输入参数是否为空或输入参数是否与条件匹配。

// 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#规范的一个片段I stole from this answer :)解释了(可能比我能做得更好)短路运算符。

  

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

     

...

     

操作x && y对应于操作x & y,但仅当yx时才评估true   操作x || y对应于操作x | y,但仅当y不是x时才评估true

     

...

     

操作x || y评估为x ? true : y。换句话说,首先评估x并将其转换为bool类型。然后,如果xtrue,则操作结果为true。否则,y将被评估并转换为bool类型,这将成为操作的结果。

答案 1 :(得分:0)

我做了一个小小的演示:

将填写您的请求的逻辑表达式是:

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

<强>含义:

(如果开始不 TRUE OR (值小于ReceptionValue)) AND (< strong> ReceptionValue 小于结束值 OR (结尾没有值为TRUE))

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);
}