我正在使用MongoDB C#Linq驱动程序来命令搜索结果显示在屏幕上的列表中。我希望能够按值可以为空的列进行排序,但始终在底部显示空值。通过以下代码使用Linq和内存集合可以实现这一点:
items.OrderByDescending(d => d.AppointmentTime.HasValue).ThenBy(d => d.AppointmentTime);
但是,当我尝试使用MongoDB C#驱动程序执行此操作时,我得到一个例外:
NotSupportedException: Unable to determine the serialization information for the expression: (d.AppointmentTime.HasValue).
我尝试使用!= null而不是HasValue,但这也不起作用。有没有办法用这种方式说服mongo没有价值?
编辑:应该说这是一个DateTime?我们正在处理的价值。我试过了
items.OrderByDescending(d => d.AppointmentTime ?? DateTime.MinValue)
但这会产生类似的NotSupportedException。
答案 0 :(得分:0)
您正在使用的LINQ语句实际上已转换为查询并发送到mongod
。您获得的异常是因为mongod
没有可空类型的概念。如果查看MongoDB文档(http://docs.mongodb.org/manual/reference/bson-types/),您会注意到mongod
只知道某个字段为空。但是只有当对该字段执行查询时,它才会意识到文档的字段为空。因此,空字段始终排在其他所有字段之下。
您可以在mongod
中执行排序,也可以在客户端的内存中执行排序。
要使用{{mongod}}排序,您应该能够简单地:
items.Where(x => x.Bar == "foo").ToArray().OrderByDescending(x => x.Widget);
为确保在内存中进行排序,必须先执行查询。这可以通过强制.ToArray()
或类似的东西来完成。因此,您可以通过执行以下操作将所有这些链接在一起:
items.Where(x => x.Bar == "foo").ToArray().OrderByDescending(x => x.Widget.HasValue).ThenBy(x => x.Widget.Value);
如果可能的话,我建议不要在客户端进行内存排序。如果您的where子句没有足够的限制,您最终可以通过网络将大量数据传输到客户端。充其量,这需要时间 - 最糟糕的是客户因资源不足而崩溃。