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

如何使用MongoDB C#驱动查询含Dictionary<Enum, int>的文档?

解决MongoDB C#驱动查询枚举键字典的问题

这个问题我之前帮朋友排查过,核心原因是MongoDB C#驱动处理枚举作为字典键的查询逻辑,和序列化时的行为没对齐——你保存数据时枚举键被序列化为数值(比如PropertyType.Age对应1),但用LINQ索引器查询时,驱动默认会尝试用枚举的字符串名称(比如"Age")去匹配字段,自然查不到数据。

下面给你几种可行的解决方案,按推荐度排序:

方案一:用强类型Filter构造查询(最推荐)

这种方式既保持类型安全,又完全匹配你当前的存储结构,不需要修改已有数据:

// 目标查询值
var targetAge = 28;
// 将枚举转换为对应的数值(和存储的键一致)
var ageEnumValue = (int)PropertyType.Age;
// 构造Filter,直接指向MongoDB中存储的字段路径
var filter = Builders<Data>.Filter.Eq($"Props.{ageEnumValue}", targetAge);
// 执行查询
var matchingDocs = collection.Find(filter).ToList();

方案二:调整LINQ查询的索引器写法

如果习惯用LINQ查询语法,只需把索引器的键换成枚举的数值类型即可:

var targetAge = 28;
var ageEnumValue = (int)PropertyType.Age;

var query = from d in collection.AsQueryable()
            where d.Props[ageEnumValue] == targetAge
            select d;

var result = query.ToList();

这里用int类型的键去索引字典,驱动会正确映射到MongoDB中存储的数值字段名(比如Props.1)。

方案三:修改序列化配置(可选,适合新数据)

如果你希望后续存储的字典键用枚举的字符串名称(比如"Age"而非1),可以配置驱动的序列化规则,这样原来的LINQ查询写法就能直接生效:

// 自定义字典序列化器,将枚举键序列化为字符串
var enumSerializer = new EnumSerializer<PropertyType>(BsonType.String);
var dictSerializer = new DictionarySerializer<PropertyType, int>(enumSerializer, BsonSerializer.SerializerRegistry.GetSerializer<int>());

// 注册自定义序列化器
BsonSerializer.RegisterSerializer(dictSerializer);

配置后,保存的数据会变成:

{ "Props": { "Age": 28, "Weight": 220, "Gender": 0 } }

这时候你原来的查询代码where d.Props[PropertyType.Age] == 28就能正常匹配到数据了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:11:32