[CSHARP-811] Update.PushEachWrapped wrap data in a wrong way adding data to a sub array Created: 29/Aug/13  Updated: 20/Mar/14  Resolved: 03/Sep/13

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.8, 1.8.1, 1.8.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Luca casali Assignee: Unassigned
Resolution: Done Votes: 0
Labels: driver
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

.net 4.0


Backwards Compatibility: Fully Compatible

 Description   

This command:

var builder = Update.PushEachWrapped("ArrayData", new List<GenericListItem>
{
new GenericListItem()

{ Name = "name", Surname = "surname" }
});


It is translated in :

{ "$push" : { "ArrayData" : { "$each" : [[{ "Name" : "name", "Surname" : "surname" }]] } } }

that is wrong, due to a [ in sub elements.

The right command translation has to be

{ "$push" : { "ArrayData" : { "$each" : [{ "Name" : "name", "Surname" : "surname" }] } } }

otherwise a sub array will be created.


The same problem is also present in :
PushAllWrapped
AddToSetEachWrapped
PushEachWrapped

There is a possible workaround forcing the conversion between IEnumerable<T> to Array. So re-writing the above code in this way

var builder = Update.PushEachWrapped("ArrayData", new List<GenericListItem>
{
new GenericListItem()
{ Name = "name", Surname = "surname" }

}.ToArray());

create a correct serialization.

It seems that the problem is located here in UpdateBuilder.cs

BsonDocumentWrapper.CreateMultiple(values).Cast<BsonValue>();
(public UpdateBuilder PushEachWrapped<T> ... raw 1309 in UpdateBuilder.cs) wrap each values in an array



 Comments   
Comment by Craig Wilson [ 29/Aug/13 ]

This is because the definition of Update.PushEachWrapped<T> takes a generic T parameter. There are 2 overloads for this method:

        public UpdateBuilder PushEachWrapped<T>(string name, IEnumerable<T> values);
        public UpdateBuilder PushEachWrapped<T>(string name, params T[] values);
 

As you aren't specifying what T is, the compiler is using type inference and determining that your type T is a List<GenericListItem> and choosing the second one. It is entirely plausable that someone would want to push a number of lists into an array, an array of arrays.

The fix for you is to declare what T is.

Update.PushEachWrapped<GenericListItem>("ArrayData", new List<GenericListItem>{ });

Generated at Wed Feb 07 21:37:54 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.