Я новичок в MongoDb, использую простой класс и вставил две записи с этой структурой в базу данных.

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}  }}";
    }
}

Я могу прочитать их по этому коду, и все в порядке.

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());
}

Результат:

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

Теперь, если я удалю Property1 из своего класса Person и снова запущу код чтения, я столкнусь с этой ошибкой:

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

Это всего лишь тестовый проект, и такие изменения в метаданных будут происходить постоянно в реальных проектах. Как мне управлять этими изменениями, чтобы избежать ошибок.

В EF и SQL Server я всегда использовал автоматические миграции, и мне не приходилось думать об изменении метаданных. Но я не знаю, что делать в случае MongoDb.

Спасибо

1
ach 26 Ноя 2016 в 15:02

2 ответа

Лучший ответ

После небольшого просмотра документации MongoDb я нашел атрибут «[BsonIgnoreExtraElements]», который работал у меня.

[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}  }}";
    }
}

Официальное объяснение таково:

Когда документ BSON десериализуется, имя каждого элемента используется для поиска соответствующего члена в карте классов. Обычно, если соответствующий элемент не найден, возникает исключение. Если вы хотите игнорировать лишние элементы во время десериализации, используйте BsonIgnoreExtraElementsAttribute

3
ach 26 Ноя 2016 в 15:47

При удалении свойства из вашей модели ваша модель и документы базы данных не синхронизируются, потому что mongo не может десериализовать документы в вашу модель. вам также следует удалить Property1 из документов mongo.

0
Masoud 26 Ноя 2016 в 13:33