[英]Check object null inside orderby Linq
我有一个list
与几个记录, list
有另一个object
里面。 基于内部对象,我正在使用OrderByDescending
。 内部对象在少数地方为null
,因此抛出NullReferenceException
。
items.OrderByDescending(i=> i.Obj_Announcement.CreatedDate).ToList()
当Obj_Announcement
为null
,查询将引发异常。
不重复:我在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语句将使用新的排序顺序。
根据期望的结果集,您基本上有两个选择。
排除实例,即Obj_Announcement
属性为null。 但是恕我直言,这不是问题的范围,它会改变程序的外观。
明确决定如何处理空值。
查看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.MinValue
和DateTime.MaxValue
只是作为默认值的假设。 它们不反映对象的实际状态。
items.OrderByDescending(i=> i.Obj_Announcement?.CreatedDate ?? DateTime.MinValue).ToList()
应该可以正常工作,就像值是null一样,它将返回DateTime.MinValue
(意味着null值将在后面),否则,您将只检索CreatedDate。
请注意,虽然我现在不在电脑前,所以无法测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.