繁体   English   中英

通过Linq检查内部对象是否为null

[英]Check object null inside orderby Linq

我有一个list与几个记录, list有另一个object里面。 基于内部对象,我正在使用OrderByDescending 内部对象在少数地方为null ,因此抛出NullReferenceException

items.OrderByDescending(i=> i.Obj_Announcement.CreatedDate).ToList()

Obj_Announcementnull ,查询将引发异常。

不重复:我在OrderByDescending有对象OrderByDescending不是单个字段。

我该如何解决这个问题?

简洁的方法是将LINQ查询与定义哪个项目位于另一个项目之前的方式分开。 换句话说:项目X和项目Y的排序顺序是什么

为此,我们需要创建一个实现IComparer<Item>

class Item
{
     public Announcement Announcement {get; set;} // your inner object, might be null
     ...
}

class Announcement
{
     public DateTime CreatedDate {get; set;}
     ...
}

假设您有两个Items ,其中一个Items Anouncement为空。

Item item1 = new Item {Announcement = null};
Item item2 = new Item {Announcement = new AnnounceMent{CreatedDate=new DateTime(2000, 1, 1)}};

由您决定哪个先出现。 假设您想在末尾输入空项目。

class ItemComparer : Comparer<Item>
{
     public static readonly ByCreatedDate = new ItemComparer();

     private static readonly IComparer<DateTime> dateComparer = Comparer<DateTime>.default;

     public override int CompareTo(Item x, Item y)
     {
         // TODO: decide what to do if x or y null: exception? comes first? comes last

         if (x.Announcement == null)
         {
             if (y.Announcement == null)
                 // x and y both have null announcement
                 return 0;
             else
                 // x.Announcement null, y.Announcement not null: x comes last:
                 return +1;
         }
         else
         {
             if (y.Announcement == null)
                 // x.Announcement not null and y.Announcement null; x comes first
                 return -1;
             else
                 // x.Announcement not null, y.Announcement not null: compare dates
                 return dateComparer.CompareTo(x.CreatedDate, y.CreateDate)
         }
    }
}

用法:

(在彼得·沃辛格(Peter Wurzinger)评论后改进)

var result = items.OrderByDescending(item => item, ItemComparer.ByCreatedDate);

注意:如果决定更改Items的排序顺序,则只需更改ItemComparer类。 然后,所有用于订购商品的LINQ语句将使用新的排序顺序。

根据期望的结果集,您基本上有两个选择。

  1. 排除实例,即Obj_Announcement属性为null。 但是恕我直言,这不是问题的范围,它会改变程序的外观。

  2. 明确决定如何处理空值。

查看OrderByDescending的文档( https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.orderbydescending )时,会遇到keySelector参数。 由于它是Func<TSource, TKey>因此它应该能够处理TSource实例可能显示的边缘情况-例如,在您的情况下,子对象上的null。 因此,恕我直言,最简单的解决方案是通过以下方式确定是否要在列表中添加空值:

items.OrderByDescending(i=> i.Obj_Announcement?.CreatedDate ?? DateTime.MinValue).ToList()

要么

items.OrderByDescending(i=> i.Obj_Announcement?.CreatedDate ?? DateTime.MaxValue).ToList()

但是请注意, DateTime.MinValueDateTime.MaxValue只是作为默认值的假设。 它们不反映对象的实际状态。

items.OrderByDescending(i=> i.Obj_Announcement?.CreatedDate ?? DateTime.MinValue).ToList()

应该可以正常工作,就像值是null一样,它将返回DateTime.MinValue (意味着null值将在后面),否则,您将只检索CreatedDate。

请注意,虽然我现在不在电脑前,所以无法测试。

暂无
暂无

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

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