我正在尝试使用 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 如何获取这些数据。它是否首先加载所有数据,正确反序列化然后过滤?还是序列化where子句的Instant
值,并使用序列化后的值过滤所有文档,加载匹配的文档,然后反序列化?
我尝试查看 mongodb 分析器记录的查询,但它似乎没有记录任何内容。我已将分析级别设置为 2。
在 Instant
的情况下,序列化值是一个 long
。但在 ZonedDateTime
的情况下,序列化值将是具有两个属性的文档。在那种情况下搜索将如何工作?
编辑:
我能够让分析工作。下面的 c# 查询,
mongoDatabase.GetCollection<SomeType>("SomeTypeCollection")
.AsQueryable<SomeType>()
.Where(x => x.Instant < Instant.FromDateTimeUtc(DateTime.UtcNow))
.ToList();
以下 mongodb 查询的结果
{ "Instant": { $lt: 13781017828460782 }}
意思是,c# 驱动程序序列化了我的 Instant
对象,并使用序列化值来过滤数据库本身中的结果。
最佳答案
驱动程序会将您的 linq 查询转换为 mongodb 查询,并在反序列化之前过滤结果。在您调用 ToList()
以下是受支持的运算符:http://docs.mongodb.org/ecosystem/tutorial/use-linq-queries-with-csharp-driver/
在驱动程序开始根据返回的数据构建对象图之前,自定义反序列化器不会发挥作用。
对于具有简单类型的类或者在阅读/编写文档时不需要做额外工作的类,您通常不需要自定义序列化程序。
如果您想控制序列化的内容,即如果您的类本质上只包含一个日期时间,为什么不存储 UTC 日期时间戳并为其他属性使用 BsonIgnore
。
关于c# - 自定义序列化程序如何影响搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18198300/