我正在尝试在我的应用程序中使用NodaTime。该应用程序将数据持久保存在 mongodb 数据库中。考虑下面的类
public class SomeType
{
public ObjectId Id { get; set; }
public Instant Instant { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
public DateTime DateTime { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime DateTimeUtc { get; set; }
// public ZonedDateTime ZonedDateTime { get; set; }
// public LocalDateTime LocalDateTime { get; set; }
}
如果不添加自定义序列化程序,Instant
类的属性不会存储在数据库中。从数据库读取文档也失败了。
public class InstantBsonSerializer : BsonBaseSerializer
{
public override object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
{
var ticks = bsonReader.ReadInt64();
return new Instant(ticks);
}
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
var ticks = bsonReader.ReadInt64();
return new Instant(ticks);
}
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
var instant = (Instant) value;
bsonWriter.WriteInt64(instant.Ticks);
}
}
我创建了上面的序列化程序并正确注册了它。我现在可以使用为Instant
.
我的问题是 C# 驱动程序如何使用 linq 处理搜索?
var list = mongoDatabase.GetCollection<SomeType>("SomeType")
.AsQueryable<SomeType>()
.Where(x => x.Instant < Instant.FromDateTimeUtc(dateTime.ToUniversalTime()))
.ToList();
Console.WriteLine(list.Count);
我得到了正确的文件清单。我试图了解 mongodb 如何获取这些数据。它是否首先加载所有数据,正确反序列化然后过滤?还是序列化Instant
where 子句的值并使用序列化的值过滤所有文档,加载匹配的文档然后反序列化?
我尝试查看 mongodb 探查器记录的查询,但它似乎没有记录任何内容。我已将分析级别设置为 2。
Instant
在序列化值的情况下是 a long
。但在 的情况下ZonedDateTime
,序列化值将是具有两个属性的文档。在这种情况下,搜索将如何工作?
编辑:
我能够让分析工作。以下 c# 查询,
mongoDatabase.GetCollection<SomeType>("SomeTypeCollection")
.AsQueryable<SomeType>()
.Where(x => x.Instant < Instant.FromDateTimeUtc(DateTime.UtcNow))
.ToList();
导致以下 mongodb 查询
{ "Instant": { $lt: 13781017828460782 }}
意思是,c# 驱动程序序列化我的Instant
对象并使用序列化的值来过滤数据库本身的结果。