From 64f6f70e65c2e7114b4a040d6583e1f69cf6fc63 Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sun, 6 Oct 2024 00:48:33 +0200 Subject: [PATCH] (bugfix): upsert and update many logics --- .../BaseCollectionDataProviderBase.cs | 57 +++++++++++++------ .../MaksIT.MongoDB.Linq.csproj | 2 +- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/MaksIT.MongoDB.Linq/Abstractions/BaseCollectionDataProviderBase.cs b/src/MaksIT.MongoDB.Linq/Abstractions/BaseCollectionDataProviderBase.cs index 61f4ee5..f63ab7b 100644 --- a/src/MaksIT.MongoDB.Linq/Abstractions/BaseCollectionDataProviderBase.cs +++ b/src/MaksIT.MongoDB.Linq/Abstractions/BaseCollectionDataProviderBase.cs @@ -89,14 +89,37 @@ namespace MaksIT.MongoDB.Linq.Abstractions { Expression> predicate, IClientSessionHandle? session) { try { - foreach (var document in documents) { - if (session != null) - await Collection.ReplaceOneAsync(session, predicate, document); - else - await Collection.ReplaceOneAsync(predicate, document); + // Step 1: Find the documents that already exist based on the predicate + List existingDocuments; + if (session != null) { + existingDocuments = await Collection.Find(session, predicate).ToListAsync(); + } + else { + existingDocuments = await Collection.Find(predicate).ToListAsync(); } - var updatedIds = documents.Select(doc => doc.Id).ToList(); + // Step 2: Get the existing document IDs + var existingIds = existingDocuments.Select(doc => doc.Id).ToHashSet(); + + // Step 3: Filter the documents to update only those that exist in the collection + var documentsToUpdate = documents.Where(doc => existingIds.Contains(doc.Id)).ToList(); + + // Step 4: Update each of the existing documents + foreach (var document in documentsToUpdate) { + // Handling nullable Id by checking both document.Id and x.Id for null + var documentPredicate = (Expression>)(x => + (x.Id == null && document.Id == null) || + (x.Id != null && x.Id.Equals(document.Id))); + + if (session != null) { + await Collection.ReplaceOneAsync(session, documentPredicate, document); + } + else { + await Collection.ReplaceOneAsync(documentPredicate, document); + } + } + + var updatedIds = documentsToUpdate.Select(doc => doc.Id).ToList(); return Result?>.Ok(updatedIds); } catch (Exception ex) { @@ -137,16 +160,18 @@ namespace MaksIT.MongoDB.Linq.Abstractions { Expression> predicate, IClientSessionHandle? session) { try { - foreach (var document in documents) { - if (session != null) { - await Collection.DeleteOneAsync(session, predicate); - await Collection.InsertOneAsync(session, document); - } - else { - await Collection.DeleteOneAsync(predicate); - await Collection.InsertOneAsync(document); - } - } + // Deletion + if (session != null) + await Collection.DeleteManyAsync(session, predicate); + else + await Collection.DeleteManyAsync(predicate); + + // Creation + if (session != null) + await Collection.InsertManyAsync(session, documents); + else + await Collection.InsertManyAsync(documents); + var upsertedIds = documents.Select(doc => doc.Id).ToList(); return Result?>.Ok(upsertedIds); diff --git a/src/MaksIT.MongoDB.Linq/MaksIT.MongoDB.Linq.csproj b/src/MaksIT.MongoDB.Linq/MaksIT.MongoDB.Linq.csproj index bef9677..44f0b95 100644 --- a/src/MaksIT.MongoDB.Linq/MaksIT.MongoDB.Linq.csproj +++ b/src/MaksIT.MongoDB.Linq/MaksIT.MongoDB.Linq.csproj @@ -8,7 +8,7 @@ MaksIT.MongoDB.Linq - 1.0.4 + 1.0.5 Maksym Sadovnychyy MAKS-IT MaksIT.MongoDB.Linq