Усиление в 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 вообще
Ответы
Ответ 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, если это необходимо.