7

I am looking for a way to conditionally combine Set operations. At the moment I have been unable to increment onto the updatedefinitions without having them consecutively dotted one after the other.

eg. instead of:

    Builders<BsonDocument>.Update.Set("someElement.Length", b.Length)
.Set("someElement.Path", b.Path)

I am trying to get find a way to use something in the vain of:

var update = Builders<BsonDocument>.Update;
bool hasChanged = false;
if (a.Length != b.Length)
{
    hasChanged = true;
    update.Set("someElement.Length", b.Length)
}
if (a.Path != b.Path)
{
    hasChanged = true;
    update.Set("someElement.Path", b.Path)
}

if (hasChanged)
    await someCollection.UpdateOneAsync(Builders<someModel>.Filter.Eq("_id", a.Id), update);

Is there a way of doing this or am I chasing a pie in the sky? I dont want to replace the entire document, and am looking to only update fields that have changed.

xxdefaultxx
  • 175
  • 1
  • 12
  • Why not just contruct the BSON document for the update directly rather than using helpers? As a BSON document, the top level key is `"$set"`, and all fields for that operation would be children of that key. It's basically just a hash/map, so the same methods apply as for adding/constructing any of those. This is really all the "helper" functions like `Set()` are really doing anyway. – Blakes Seven Mar 08 '16 at 10:47
  • Ok sounds interesting so it would be { $set: { someElement.length: B.length, someElement.path: b.path } } etc etc with the actual values instead. If so then your right. Thats alot easier and I can easily see how such functionality would be powerful. – xxdefaultxx Mar 08 '16 at 12:21
  • I know the documentation follows the "shell" convention and therefore examples are in JSON, but if you basically think in terms that the eventual BSON looks pretty much the same ( in abstract terms ) then its's just a matter of construction. You would do a lot better to familarize with core documentation than driver documentation. See [`$set`](https://docs.mongodb.org/manual/reference/operator/update/set/). Of course I'm right. – Blakes Seven Mar 08 '16 at 12:27
  • Thanks for the advice I wasn't questioning your accuracy only my interpretation. I'll def focus more on the core docs. Appreciated. Btw. If you can write in an example as an answer I can mark your answer as being the solution. – xxdefaultxx Mar 08 '16 at 12:54

2 Answers2

14

UpdateDefinition is an immutable object, so chaining operations on them keeps creating a new one each time. To do it conditionally, you need assign the result back to itself, just like LINQ.

update = update.Set(...);

Craig Wilson
  • 12,174
  • 3
  • 41
  • 45
1

If you maintain a collection of your conditionally created UpdateDefinitions, you can pass that collection into the Combine operator to create your final UpdateDefinition.

You can find an example on this similar question: C# MongoDB Driver - How to use UpdateDefinitionBuilder?

mrfmunger
  • 11
  • 3