How to read data from Mongodb which have duplicate element name in c# How to read data from Mongodb which have duplicate element name in c# mongodb mongodb

How to read data from Mongodb which have duplicate element name in c#


If nothing else helps, you reviewed other answers and comments, and still think you absolutely must keep design described in your question, you can use the following hack. Create class like this:

class AlwaysAllowDuplicateNamesBsonDocumentSerializer : BsonDocumentSerializer {    protected override BsonDocument DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args) {        if (!context.AllowDuplicateElementNames)            context = context.With(c => c.AllowDuplicateElementNames = true);        return base.DeserializeValue(context, args);    }    public override BsonDocument Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) {        if (!context.AllowDuplicateElementNames)            context = context.With(c => c.AllowDuplicateElementNames = true);        return base.Deserialize(context, args);    }}

This is custom serializer for BsonDocument which always sets AllowDuplicateElementNames while deserializing. Then you need a bit of reflection to overwrite default BsonDocument serializer (because BsonDocumentSerializer.Instance has no setter):

// get __instance field, which is backing field for Instance propertyvar instanceField = typeof(BsonDocumentSerializer).GetField("__instance", BindingFlags.Static | BindingFlags.NonPublic);// overwrite with our custom serializerinstanceField.SetValue(null, new AlwaysAllowDuplicateNamesBsonDocumentSerializer());

By doing that somewhere at startup you will be able to read back your documents with duplicated attributes.

Full code for test:

static void Main(string[] args) {    var instanceField = typeof(BsonDocumentSerializer).GetField("__instance", BindingFlags.Static | BindingFlags.NonPublic);    instanceField.SetValue(null, new AlwaysAllowDuplicateNamesBsonDocumentSerializer());    TestMongoQuery();    Console.ReadKey();}static async void TestMongoQuery() {    var client = new MongoClient();    var db = client.GetDatabase("Test_DB");                var collection = db.GetCollection<BsonDocument>("TestTable");    using (var allDocs = await collection.FindAsync(FilterDefinition<BsonDocument>.Empty)) {        while (allDocs.MoveNext()) {            foreach (var doc in allDocs.Current) {                var duplicateElements = doc.Elements.Where(c => c.Name == "DuplicateCol");                foreach (var el in duplicateElements) {                    Console.WriteLine(el.Name + ":" + el.Value);                }            }        }    }}


The error you receive is by design

InvalidOperationException: Duplicate element name 'DuplicateCol'

As CodeFuller said, MongoDB document keys should be unique. If you need a document to contain duplicate field names and you cannot alter this schema, MongoDB might not be the right database solution for you....I don't know which one will to be honest. Although it does seem possible to save duplicate keys using:

AllowDuplicateNames=true

I imagine you will experience challenges with querying and indexing, among others.

An argument could be made that this schema is a very strange requirement. A more appropriate schema might be:

{    "_id" : ObjectId("xxx"),    "propTest" : 0,    ...    "duplicateCol": [ "Value_Two", "Value_One" ]}

Here you have a single property (duplicateCol) which is an array which accepts multiple strings.