Подтвердить что ты не робот

Усиление в Mongo DB и проблема Id

У меня возникла проблема, когда вы возвращаетесь к mongo db с помощью официального драйвера С#.

public abstract class AggregateRoot
{
    /// <summary>
    /// All mongoDb documents must have an id, we specify it here
    /// </summary>
    protected AggregateRoot()
    {
        Id = ObjectId.GenerateNewId();
    }

    [BsonId]
    public ObjectId Id { get; set; }
}

У моих сущностей уже есть идентификаторы, но мне нужно было создать идентификатор mongo для его работы, так как все документы в коллекции должны иметь один. Теперь я получаю новую сущность в своей системе, генерируется новый Mongo Id, и я могу заставить mongo не изменять _id исключения из старого документа. Есть ли какая-нибудь работа?

Позвольте мне немного описать дизайн. Все объекты, которые будут хранятся как документы, наследуемые от AggregateRoot, которые имели id в нем. Каждый поддокумент имел свой идентификатор автоматически, и у меня не было проблем с этим. Идентификатор в AggregateRoot был введен для устранения проблемы при получении данных из MongoCollection to List и генерация была введена так, что id-s разные. Теперь мы можем переместить это поколение id для сохранения методов потому что новый объект для обновления имел новое поколение идентификаторов. Но это будет означать, что каждый разработчик в команде не должен забывать генерировать id-s в хранилище, которое является рискованным. Было бы лучше просто игнорировать идентификатор чем отображение из монго, если это возможно, и не иметь Класс AggregateRoot вообще

4b9b3361

Ответ 1

Похоже, вы можете явно указать значение Id для обеих вставок и обновлений. Это прекрасно для вставок, для всех новых объектов требуется значение _id, однако для обновлений вам не разрешено изменять значение _id в существующем документе после его создания.

Не пытайтесь установить значение Id. Если вы не укажете значение перед вставкой, драйвер использует встроенные классы IdGenerator для генерации нового значения _id, поэтому, если он тип ObjectId, он будет использовать ObjectIdGenerator. Тогда ваши вставки и обновления работают нормально.

Ответ 2

Я столкнулся с подобной проблемой. Я хотел обновить документы, используя официальный драйвер С#. У меня был класс вроде этого:

public class MyClass
{
    public ObjectId Id { get; set; }
    public int Field1 { get; set; }
    public string Field2 { get; set; }
}

В консоли я бы написал: db.collection.update({Field1: 3},{Field1: 3, Field2: "value"}), и это сработает. В С# я писал:

collection.Update(Query.EQ("Field1", 3),
                Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }),
                UpdateFlags.Upsert);

и это не сработало! Поскольку драйвер включает пустой идентификатор в операторе обновления и когда я обновляю второй документ с другим значением исключения Field1 E11000 duplicate key error index (в этом случае Mongo пытается вставить документ с _id, который уже существует в db).

Когда я сгенерировал _id сам (например, стартер темы), я столкнулся с тем же исключением (mongo cannot change _id of a document) при воссоздании объектов с существующим значением поля1.

Решение заключается в том, чтобы пометить свойство Id атрибутом [BsonIgnoreIfDefault] (и не инициализировать его). В этом случае драйвер опускает поле _id в операторе обновления, а MongoDb генерирует Id, если это необходимо.