MongoDB使用C#Linq驱动程序订购可空类型

时间:2014-01-24 11:37:44

标签: c# linq mongodb sorting nullable

我正在使用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。

1 个答案:

答案 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子句没有足够的限制,您最终可以通过网络将大量数据传输到客户端。充其量,这需要时间 - 最糟糕的是客户因资源不足而崩溃。