ach
ach

Reputation: 303

MongoDb.Driver throws exception when I remove entity class property

I'm new to MongoDb and using a simple class and inserted two records with this structure into a database.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Property1 { get; set; }

    public override string ToString()
    {
        return $"{{ Id: {Id}, Name: {Name}  }}";
    }
}

I can read them by this code and everything is fine.

var client = new MongoClient();
var db = client.GetDatabase("test-update");
var people = db.GetCollection<Person>("people").Find(p => true).ToList();

foreach (var person in people)
{
    Console.WriteLine(person.ToString());
}

The result is:

{ Id: 1, Name: person 1  }
{ Id: 2, Name: person 2  }

Now if I remove the Property1 from my Person class, and run the read code again, I'll run into this error:

Unhandled Exception: System.FormatException: Element 'Property1' does not match any field or property of class Person.
   at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.DeserializeClass(BsonDeserializationContext context)
   at MongoDB.Bson.Serialization.BsonClassMapSerializer`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
   at MongoDB.Driver.Core.Operations.CursorBatchDeserializationHelper.DeserializeBatch[TDocument](RawBsonArray batch, IBsonSerializer`1 documentSerializer, MessageEncoderSettings messageEncoderSet
tings)
   at MongoDB.Driver.Core.Operations.FindCommandOperation`1.CreateCursorBatch(BsonDocument result)
   at MongoDB.Driver.Core.Operations.FindCommandOperation`1.ExecuteCommand(IReadBinding binding, ServerDescription serverDescription, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.FindCommandOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.FindOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken)
   at MongoDB.Driver.OperationExecutor.ExecuteReadOperation[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IReadOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.FindSync[TProjection](FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.FindFluent`2.ToCursor(CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.ToList[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)
   at ConsoleApplication.Program.Main(String[] args) in C:\Users\choro\Desktop\mongo-update\Program.cs:line 12

This is just a test project and these kind of changes in metadata would be happened all the time in real projects. How do I manage these changes to avoid errors.

In EF and SQL Server I always used Automatic Migrations and didn't have to think about the metadata changes. But I don't know what to do in case of MongoDb.

Thanks

Upvotes: 2

Views: 2331

Answers (2)

ach
ach

Reputation: 303

After a little browsing in MongoDb documentation, found an attribute '[BsonIgnoreExtraElements]' that worked for me.

[BsonIgnoreExtraElements]
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    //public string Property1 { get; set; }

    public override string ToString()
    {
        return $"{{ Id: {Id}, Name: {Name}  }}";
    }
}

The official explanation is this:

When a BSON document is deserialized, the name of each element is used to look up a matching member in the class map. Normally, if no matching member is found, an exception will be thrown. If you want to ignore extra elements during deserialization, use a BsonIgnoreExtraElementsAttribute

Upvotes: 6

ihsan
ihsan

Reputation: 87

By removing a property from your model, your model and database documents isn't in sync, cause mongo cannot deserialize documents to your model. you should remove Property1 from mongo documents too.

Upvotes: 0

Related Questions