При попытке выполнить операцию upsert в Mongo, я хотел бы, чтобы он генерировал идентификатор GUID для идентификатора вместо идентификатора объекта. В этом случае я проверяю, чтобы объект со специфическими свойствами еще не существовал и фактически выдавал исключение, если обновление происходит.MongoDB C# Upsert with Guid
Вот заглушки из определения класса:
public class Event
{
[BsonId(IdGenerator = typeof(GuidGenerator))]
[BsonRepresentation(BsonType.String)]
[BsonIgnoreIfDefault]
public Guid Id { get; set; }
// ... more properties and junk
}
А вот как мы выполняем операцию upsert:
// query to see if there are any pending operations
var keyMatchQuery = Query<Event>.In(r => r.Key, keyList);
var statusMatchQuery = Query<Event>.EQ(r => r.Status, "pending");
var query = Query.And(keyMatchQuery , statusMatchQuery);
var updateQuery = new UpdateBuilder();
var bson = request.ToBsonDocument();
foreach (var item in bson)
{
updateQuery.SetOnInsert(item.Name, item.Value);
}
var fields = Fields<Request>.Include(req => req.Id);
var args = new FindAndModifyArgs()
{
Fields = fields,
Query = query,
Update = updateQuery,
Upsert = true,
VersionReturned = FindAndModifyDocumentVersion.Modified
};
// Perform the upsert
var result = Collection.FindAndModify(args);
делая это таким образом будет генерировать идентификатор в качестве ObjectID, а не GUID.
Я могу определенно получить поведение я хочу, как операции в два этапа, выполняя .FindOne первый, и если это не удается, делая прямую вставку:
var existingItem = Collection.FindOneAs<Event>(query);
if (existingItem != null)
{
throw new PendingException(string.Format("Event already pending: id={0}", existingItem.Id));
}
var result = Collection.Insert(mongoRequest);
В этом случае, он правильно устанавливает GUID для нового элемента, но операция неатомная. Я искал способ, чтобы установить механизм по генерации ID по умолчанию на уровне драйвера, и думал, что это будет сделать это:
BsonSerializer.RegisterIdGenerator(typeof(Guid), GuidGenerator.Instance);
... но безрезультатно, и я предполагаю, что это потому, что для upsert , поле ID не может быть включено, поэтому сериализация не происходит, и Mongo выполняет всю работу. Я также изучил реализацию конвенции, но это не имело смысла, поскольку для этого есть отдельные механизмы генерации. Есть ли другой подход, на который я должен смотреть, и/или я просто что-то пропустил?
Я действительно понимаю, что GUID не всегда идеальны в Монго, но мы изучаем их использование из-за совместимости с другой системой.
Введенная здесь ссылка помогла ответить на мой вопрос в сочетании с предоставленной информацией. Описанный сценарий был именно тем, с чем мы столкнулись. Мы изучаем, какую версию Монго мы установили, и можем ли мы ее обновить, потому что в настоящее время у нас есть несколько версий. – Masaka