【问题标题】:Using parameter in Linq that might be null在 Linq 中使用可能为空的参数
【发布时间】:2016-03-16 19:21:44
【问题描述】:

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

where beginning <= time && time <= end

有没有办法不用 if、if else、else 语句就能写出这些情况?

【问题讨论】:

    标签: c# linq


    【解决方案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# 规范的一个 sn-p,I stole from this answer :) 解释了(可能比我能解释的更好)关于短路操作符。

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

    ...

    操作x &amp;&amp; y 对应于操作x &amp; y,除了y 仅在xtrue 时才被评估
    操作x || y 对应于操作x | y,除了y 仅在x 不是true 时才被评估。

    ...

    操作x || y 被评估为x ? true : y。换句话说,x 首先被评估并转换为类型bool。那么,如果xtrue,则运算结果为true。否则,y 被求值并转换为类型bool,这将成为操作的结果。

    【讨论】:

    【解决方案2】:

    我做了一个小示范:

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

    (!start.HasValue || start &lt; we.Reception) &amp;&amp; (we.Reception &lt; end || !end.HasValue)

    意思:

    (如果 start 没有value TRUE OR(值小于 ReceptionValue))AND(ReceptionValue 小于 end value OR(end 没有值为 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2015-12-22
      相关资源
      最近更新 更多