[CSHARP-292] There should be a way to join several UpdateBuilder instances into a complete update expression (IMongoUpdate) Created: 31/Jul/11 Updated: 02/Apr/15 Resolved: 05/Aug/11 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Feature Request |
| Affects Version/s: | None |
| Fix Version/s: | 1.2 |
| Type: | Improvement | Priority: | Minor - P4 |
| Reporter: | Roman Kuzmin | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Backwards Compatibility: | Fully Compatible |
| Description |
|
For example a new constructor of UpdateDocument: UpdateDocument(IEnumerable<UpdateBuilder>). UpdateBuilder chains do not cover all practical scenarios well. My application creates update pieces for each field separately. Pseudo code: UpdateBuilder Method1() { return Update.Set("filed1", value1); }UpdateBuilder Method2() { return Update.Set("filed2", value2); }... As a result, in a method that calls Method1, Method2, ..., MethodN I have a collection of update expressions, one per a field. The driver does not provide an easy way to join these pieces into a single update expression to be used in Update() methods. Instead, we have to create a starter empty UpdateBuilder, send it to all methods, and methods have to be a bit more complex: UpdateBuilder Method1(UpdateBuilder builder) { return builder.Set("filed1", value1); }UpdateBuilder Method2(UpdateBuilder builder) { return builder.Set("filed2", value2); }... """"" Real scenario: it shows that even Method(UpdateBuilder) approach is not enough for all """"" In fact, my application is a PowerShell module designed for MondoDB + C# driver. Update-Data $collection $query @( The last argument of Update-Data cmdlet (it calls Update() on $collection) is a collection of update expressions produced by one or more calls of the Set-Value cmdlet (gets an update expression for a single field). But this desirable code is now not supported due to lack of a proposed driver method. I cannot even use Method(UpdateBuilder) approach because the expression @(..) is evaluated before the call to Update-Data and there is no chance to initiate a starter UpdateBuilder to be sent to Set-Value cmdlets even implicitly (say, as a hidden internal variable shared between Set-Value calls). Instead, I have to make the Set-Value cmdlet to accept optional UpdateBuilder input via pipeline. So that I have to emulate UpdateBuilder chains in a peculiar way. And the code above right now actually has to look like this: Update-Data $collection $query ( ` So that the first call to Set-Value initiates a starter UpdateBuilder and sends it to other Set-Value-s. The required UpdateBuilder chain is emulated. Well, it is not that bad and the job is done. But it is not pretty either: *) Pipelines (|) are basically expensive in PowerShell and better be avoided Update-Data $collection $query $updates """""""""" Of course, I can go to lower level and do that $set, etc. things on my own. But I think the purpose of the driver is to do such low level jobs and let users to concentrate on their application code instead. Ideally, a user of C# driver should not have to know MongoDB query/update expression syntax details. |
| Comments |
| Comment by Roman Kuzmin [ 06/Aug/11 ] |
|
Robert, Thank you. This is exactly what I was asking for. As a result, I got rid of my extra helper class. All now works in simple and natural way. NB: It was needed for C# API in the first place. PowerShell was mentioned just as an example of a scenario that triggered the issue. The new Combine() method I actually consume in C# (but for PowerShell, yes). |
| Comment by Robert Stam [ 05/Aug/11 ] |
|
The static method Update.Combine combines a variable number of UpdateBuilders into one single new UpdateBuilder. The instance method UpdateBuilder.Combine combines one other UpdateBuilder into an existing UpdateBuilder. I assume the static method will do what you wanted to do in Powershell. Let me know if it does not. |
| Comment by Roman Kuzmin [ 31/Jul/11 ] |
|
OK, I have found a way to make desirable syntax to work in PowerShell scripts. But this is rather rocket science comparing to how easy it could be instead if we are able to join update expressions Here it is, just in case if anybody interested. =1= public UpdateField(Func<UpdateBuilder, UpdateBuilder> build) { Build = build; }public override string ToString() { return Build(new UpdateBuilder()).ToString(); }} =2= =3= All in all, now I can do this in PowerShell: Update-Data $collection $query @( Or even more dynamic (with true chain/pipeline approach that would not be so easy): Update-Data $collection $query @( Set-Value filedN valueN |