为何带[BsonId(GuidGenerator)]的字段生成空UUID?如何生成有效GUID?
问题原因
- MongoDB .NET驱动默认只给根集合文档自动触发
IdGenerator生成逻辑,嵌套在文档里的子对象(比如DataSource作为Document的列表元素)不属于独立集合,驱动不会主动调用它的IdGenerator生成GUID,所以Id会保留Guid的默认值(全0)。 - 另外,
[BsonId]标记在嵌套对象上时,驱动不会把它当成需要自动生成的主键——主键概念只针对集合里的根文档。
解决方案
以下是几种可行的处理方式:
1. 手动生成GUID(最简单直接)
创建DataSource实例时,直接给Id赋值:
var dataSource = new DataSource { Id = Guid.NewGuid(), Alias = "示例数据源" }; var document = new Document { DataSourceList = new List<DataSource> { dataSource } }; // 保存文档 collection.InsertOne(document);
2. 配置驱动约定自动生成嵌套对象的Id
通过驱动约定,让序列化DataSource对象时自动生成未赋值的Id:
var conventionPack = new ConventionPack { new IdGeneratorConvention(typeof(GuidGenerator)) }; ConventionRegistry.Register("NestedIdGenerator", conventionPack, t => t == typeof(DataSource)); // 初始化客户端时应用该约定 var client = new MongoClient("mongodb://localhost:27017");
3. 给DataSource的Id设默认值
直接在类里给Id设置默认值,实例化时自动生成GUID:
public class DataSource { [BsonId(IdGenerator = typeof(GuidGenerator))] public Guid Id { get; set; } = Guid.NewGuid(); [BsonRequired] public string Alias { get; set; } }
4. 忽略空GUID存储(可选)
如果不需要子对象的Id,可以加[BsonIgnoreIfDefault]属性,避免把全0的GUID存入数据库:
public class DataSource { [BsonId(IdGenerator = typeof(GuidGenerator))] [BsonIgnoreIfDefault] public Guid Id { get; set; } [BsonRequired] public string Alias { get; set; } }
注意:这种方式不会生成有效GUID,只是不存储空值,适合不需要子对象Id的场景。
内容的提问来源于stack exchange,提问作者Ayal
相关产品推荐
相关产品推荐

