重复元素错误MongoDB .Net Core 3.0



我正在努力将MongoDB集成到C#项目中,遇到了一个我找不到解决方案的问题。 该代码来自 Xunit 测试类。 我首先创建一个简单的 Bson 对象,然后将其插入到我的集合中。 这行得通。 然后,我查询记录以确保它在集合中。 此时,我收到一个 System.InvalidOperationException : 重复的元素名称"title"错误。

这是我的模拟布森:

// Create mock List<Bson Document>
public class MongoUtilsBson : IEnumerable<object[]>
{
BsonDocument bson = new BsonDocument();
List<BsonDocument> bsonList = new List<BsonDocument>();
public MongoUtilsBson()
{
bson.Add("id", "TestId");
bson.Add("title", "Test Title");
bson.Add("owners", new BsonArray() { "TestOwner" });
bson.Add("modifiedDate", "TestDate");
bsonList.Add(bson);
}
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] { bsonList };
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

这是我的测试类:

public class SheetsDataConverterTest
{
[Theory]
[ClassData(typeof(MongoUtilsBson))]
public async Task MongoInsertShouldInsertToSheetsDataCollection(List<BsonDocument> bsonDocuments)
{
// Arrange
SheetsDataConverter.MongoInsert(bsonDocuments).Wait(); // Run synchronously
// Act
MongoDBConnect mongoDBConnect = new MongoDBConnect("GoogleExchange");
var result = await mongoDBConnect.DataSelectAsync(@"{}", "SheetsData");
// Assert
Assert.True(result.Count == 1);
// Cleanup
await mongoDBConnect.DataDeleteAsync(@"{ id : ""TestId"" }", "SheetsData");

}
}

下面是 SheetsDataConverter 类(这是指定在调用方法和 Mongo 连接类之间使用的参数(:

public static class SheetsDataConverter
{
public static async Task MongoInsert(List<BsonDocument> bsonDocuments)
{
SheetsDataClassMap.Register();
List<SheetsDataModel> insertDocuments = new List<SheetsDataModel>();
var m = UtilitiesFactory.ConnectMongo("GoogleExchange");
foreach (BsonDocument doc in bsonDocuments)
{
BsonDocument cleanDoc = MongoUtils.bsonClean(doc); // Remove periods from key names
SheetsDataModel sdm = new SheetsDataModel()
{
id = cleanDoc.GetElement("id").Value.AsString,
Title = cleanDoc.GetElement("title").Value.AsString,
owners = cleanDoc.GetElement("owners").Value.AsBsonArray,
modifiedDate = cleanDoc.GetElement("modifiedDate").Value.AsString,
extraElements = cleanDoc.AsBsonDocument
};
insertDocuments.Add(sdm);
}
int result = await m.DataUpsertManyAsync("SheetsData", insertDocuments);
}
}

有一个类映射,用于定向正在插入的数据,但不在FindAsync(query)方法上引用。

班级地图:

public class SheetsDataClassMap
{
public static void Register()
{
if (!BsonClassMap.IsClassMapRegistered(typeof(SheetsDataModel)))
{
BsonClassMap.RegisterClassMap<SheetsDataModel>(cm =>
{
cm.AutoMap();
cm.SetIsRootClass(true);
cm.GetMemberMap(c => c.id).SetElementName("id");
cm.GetMemberMap(c => c.Title).SetElementName("title");
cm.GetMemberMap(c => c.owners).SetElementName("owners");
cm.GetMemberMap(c => c.modifiedDate).SetElementName("modifiedDate");
cm.MapExtraElementsMember(c => c.extraElements);
});
}
}
}

记录已正确插入,但在调用await mongoDBConnect.DataSelectAsync(@"{}", "SheetsData");时,该方法会给出错误。

该方法调用:

public async Task<List<BsonDocument>> DataSelectAsync(string query, string collection)
{
IMongoCollection<BsonDocument> coll = db.GetCollection<BsonDocument>(collection);
var result = await coll.FindAsync(query); // Fails here
List<BsonDocument> list = result.ToList();
return list;
}

我可以在 Compass 和 Mongo shell 中使用查找函数来获取记录,所以我不知道 .Net 不会解析它的记录有什么问题。 由于 .Net 插入了它,并且重复条目上下文设置为 false,因此它根本不应该有任何重复的元素。 我可以直接将记录发布到集合中,并通过 .Net 将记录重新发布出来,所以我怀疑它与我的类地图有关。 但是,在审讯Bson时,记录中没有重复。

下面是堆栈跟踪:

Message: 
System.InvalidOperationException : Duplicate element name 'title'.
Stack Trace: 
BsonDocument.Add(BsonElement element)
BsonDocument.Add(String name, BsonValue value)
BsonDocumentSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
BsonValueSerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
CursorBatchDeserializationHelper.DeserializeBatch[TDocument](RawBsonArray batch, IBsonSerializer`1 documentSerializer, MessageEncoderSettings messageEncoderSettings)
FindCommandOperation`1.CreateCursorBatch(BsonDocument commandResult)
FindCommandOperation`1.CreateCursor(IChannelSourceHandle channelSource, BsonDocument commandResult)
FindCommandOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
FindOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
FindOperation`1.ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
OperationExecutor.ExecuteReadOperationAsync[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken)
MongoCollectionImpl`1.ExecuteReadOperationAsync[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
MongoDBConnect.DataSelectAsync(String query, String collection) line 26
SheetsDataConverterTest.MongoInsertShouldInsertToSheetsDataCollection(List`1 bsonDocuments) line 23
--- End of stack trace from previous location where exception was thrown ---

任何帮助不胜感激!

我能够纠正这个问题。 问题是 DataSelectAsync 方法中的集合声明。 我将数据作为 Bson 对象引入,该对象在反序列化期间失败。

旧代码:

public async Task<List<BsonDocument>> DataSelectAsync(string query, string collection)
{
IMongoCollection<BsonDocument> coll = db.GetCollection<BsonDocument>(collection)

新代码:

public async Task<List<T>> DataSelectAsync<T>(string query, string collection, T classData) where T : class
{
IMongoCollection<T> coll = db.GetCollection<T>(collection);

集合类型的泛型声明通过类映射发送结果,并绕过 Bson 反序列化。

最新更新