You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#操作MongoDB聚合查询时如何反序列化DateTimeOffset类型

问题根源

MongoDB C# 驱动默认会将DateTimeOffset类型序列化为长度为2的数组存储:第一个元素存储UTC时间的Ticks值,第二个元素存储相对UTC的偏移分钟数,你在数据库里看到的[NumberLong(637919607231619015), 0]就是这个序列化结构。
聚合管道返回的是原始Bson文档,驱动不会自动做类型映射,因此theFirstItem["firstDate"]实际是BsonArray类型,直接调用ToUniversalTime()就会抛出你遇到的不支持异常。

可行解决方案

方法1:手动解析BsonArray取值

直接按照DateTimeOffset的存储结构从返回的Bson数组里读取值,手动构造对应类型即可:

var dateArray = theFirstItem["firstDate"].AsBsonArray;
var utcTicks = dateArray[0].AsInt64;
var offsetMinutes = dateArray[1].AsInt32;
DateTimeOffset firstDate = new DateTimeOffset(utcTicks, TimeSpan.FromMinutes(offsetMinutes));
// 需要UTC时间直接取属性即可
DateTime firstDateUtc = firstDate.UtcDateTime;

方法2:定义强类型结果类,让驱动自动反序列化

给聚合返回的结果定义对应的实体类,聚合时直接指定返回类型,驱动会自动完成DateTimeOffset的类型转换,不需要手动处理Bson结构:

// 定义聚合返回结果的实体
class GroupResult
{
    public int _id { get; set; }
    public DateTimeOffset firstDate { get; set; }
}

// 聚合时指定返回类型为GroupResult
var theFirstItem = collection.Aggregate<TheThing>()
    .Group(new BsonDocument
    {
        // 这里修正了你原代码的笔误:分组字段要加$前缀,否则_id会固定为字符串"Number"
        { "_id", "$Number" },
        { "firstDate", new BsonDocument { { "$first", "$Date" } } }
    })
    .As<GroupResult>()
    .First();

// 直接读取属性即可,不需要额外转换
var firstDate = theFirstItem.firstDate;

额外提醒:你原代码Group阶段的_id配置少了$前缀,写的是"Number",这会导致所有数据分到同一组,_id值为固定字符串"Number",和你贴出来的返回结果里"_id":1的预期不符,上面代码已经修正了这个问题。

内容的提问来源于stack exchange,提问作者Marcello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:39:40