c# - 访问新保存对象上的 ID 时 MongoDB C# 驱动程序 InvalidOperationException
问题描述
我正在使用 C# 驱动程序 V2.9.3 在 MongoDB 中保存一个项目。
我看到偶尔会抛出以下异常(尽管一旦它发生一次,它似乎更容易再次发生)。
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
at MongoDB.Bson.Serialization.Serializers.DictionarySerializerBase`3.SerializeDocumentRepresentation(BsonSerializationContext context, TDictionary value)
at MongoDB.Bson.Serialization.Serializers.ClassSerializerBase`1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value)
at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Serialize(IBsonSerializer serializer, BsonSerializationContext context, Object value)
at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.SerializeClass(BsonSerializationContext context, BsonSerializationArgs args, TClass document)
at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, TClass value)
at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Serialize(IBsonSerializer serializer, BsonSerializationContext context, Object value)
at MongoDB.Bson.Serialization.Serializers.BsonValueSerializerBase`1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, TBsonValue value)
at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Serialize(IBsonSerializer serializer, BsonSerializationContext context, Object value)
at MongoDB.Bson.Serialization.Serializers.BsonValueSerializerBase`1.Serialize(BsonSerializationContext context, BsonSerializationArgs args, TBsonValue value)
at MongoDB.Driver.Core.WireProtocol.Messages.Encoders.BinaryEncoders.CommandMessageBinaryEncoder.WriteType1Section(BsonBinaryWriter writer, Type1CommandMessageSection section, Int64 messageStartPosition)
at MongoDB.Driver.Core.WireProtocol.Messages.Encoders.BinaryEncoders.CommandMessageBinaryEncoder.WriteSections(BsonBinaryWriter writer, IEnumerable`1 sections, Int64 messageStartPosition)
at MongoDB.Driver.Core.WireProtocol.Messages.Encoders.BinaryEncoders.CommandMessageBinaryEncoder.WriteMessage(CommandMessage message)
at MongoDB.Driver.Core.Connections.BinaryConnection.SendMessagesHelper.EncodeMessages(CancellationToken cancellationToken, List`1& sentMessages)
at MongoDB.Driver.Core.Connections.BinaryConnection.SendMessagesAsync(IEnumerable`1 messages, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken)
at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocolAsync[TResult](IWireProtocol`1 protocol, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.RetryableWriteOperationExecutor.ExecuteAsync[TResult](IRetryableWriteOperation`1 operation, RetryableWriteContext context, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase`1.ExecuteBatchAsync(RetryableWriteContext context, Batch batch, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase`1.ExecuteBatchesAsync(RetryableWriteContext context, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.ExecuteBatchAsync(RetryableWriteContext context, Batch batch, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.ExecuteAsync(IWriteBinding binding, CancellationToken cancellationToken)
at MongoDB.Driver.OperationExecutor.ExecuteWriteOperationAsync[TResult](IWriteBinding binding, IWriteOperation`1 operation, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.ExecuteWriteOperationAsync[TResult](IClientSessionHandle session, IWriteOperation`1 operation, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.BulkWriteAsync(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionBase`1.InsertOneAsync(TDocument document, InsertOneOptions options, Func`3 bulkWriteAsync)
at MyApp.Program.MongoDbResultSaver.Save(PhishingResult result, IEmailHolder email) line 107
at MyApp.Program.Services.MongoDbResultSaver.Save(PhishingResult result, IEmailHolder email) line 121
请参阅下面的我的编辑代码
try
{
var obj= new MyDbObject()
{
ID = Guid.NewGuid().ToString(),
// meny propertys including objects, and lists of objects
};
var metaCollection = db.GetCollection<MyDbObject>("MyDbObject");
await metaCollection.InsertOneAsync(obj);
_logger.Info("Saved with ID " + obj.ID);//line 107 in stack trace where the error is coming from
}
catch (Exception e)
{
_logger.Error($"Failed to save metastore with error {e}");
throw;//line 121 in stacktrace where the error is being rethrown
}
以及对象定义的相关部分
[BsonIgnoreExtraElements]
public class MyDbObject
{
[BsonId]
public string ID { get; set; }
[BsonElement("etc")]
//etc
}
感谢您提供任何帮助,我们仅在使用 mongodb atlas M10 实例作为服务器的生产中观察到这种情况。
解决方案
您可以使用 ObjectId 作为文档的唯一标识符。
try
{
var obj= new MyDbObject()
{
ID = ObjectId.GenerateNewId(),
// many properties including objects, and lists of objects
};
var metaCollection = db.GetCollection<MyDbObject>("MyDbObject");
await metaCollection.InsertOneAsync(obj);
_logger.Info("Saved with ID " + obj.ID);//line 107 in stack trace where the error is coming from
}
catch (Exception e)
{
_logger.Error($"Failed to save metastore with error {e}");
throw;//line 121 in stacktrace where the error is being rethrown
}
对象模型将是,
[BsonIgnoreExtraElements]
public class MyDbObject
{
[BsonId]
public ObjectId ID { get; set; }
[BsonElement("etc")]
//etc
}
推荐阅读
- python - 我的自定义宏在我的电脑上工作,但在目标电脑上崩溃
- tomcat - 如何在 Tomcat 9 上使用撒克逊语
- c# - 碰撞时发送消息?
- shell - SHCreateItemFromParsingName() 是否需要完整路径?
- mysql - 无法在 MySQL 5.7 中更改表列类型
- python - AttributeError:“MyGrid”对象没有我的函数的属性
- python - NameError : 变量未定义
- rust - 将泛型类型限制为原始数字类型
- google-chrome - 紧循环后如何恢复 Chrome?
- json - SQL Server:如何将所有行作为 Json 对象查询到其他列旁边?