如何使用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
相关产品推荐
相关产品推荐

