0

I've a Parent Entity that has a property of list of Child Entities. Initially on Insert I don't have values for the child entities.

But when I try to Update(by calling push) the document with Child Entities it fails.
This works when I insert a dummy child entity value to the Initial Add .

This is because the embedded document refers to null .

public class ParentDocument : Entity
{

    public string prop1 { get; set; }        
    public List<EmbeddedDocument> EmbeddedDocuments { get; set; }
}
public class EmbeddedDocument
{
    public string prop2{ get; set; }

}  

The parent is saved First

_collection.InsertOne(new ParentDocument(){prop1 ="value"});

and later when I Update the document

var builder = Builders<ParentDocument>.Update;
var updateDefintion = builder.Push(x => x.EmbeddedDocuments ,new EmbeddedDocument() { prop2= "value2" });
 _collection.UpdateManyAsync(x=>x.Id==ParentDocumentId, updateDefinition)

error occurs "A write operation resulted in an error mongodb"

But this push works if I have already inserted Embedded Document(s) in the List on first insert.
I think that is because of that the EmbeddedDocuments property is Inserted as null the push doesn't work.

I also tried passing empty List to intial Insert,but not helped.

One Idea would be to check if the count of List of Embedded documents is zero and call

Builder.set(x=>x.EmbeddedDocuments ,new List<EmbeddedDocument>(){ item1 });

But this will cost a query , which I don't want to.

Is there any other solution?

Thanks in Advance

8
  • Are you absolutely sure the document you are updating doesn't already have a field that is not an array of the same name for the array property you wish to update? Errors generally occur when this is the case due to a BSON type mismatch. Otherwise a $push operation will just create a new array with the entry (or entries) as supplied. Commented Jun 9, 2015 at 11:09
  • Why not just have an empty list there in the first place? Commented Jun 9, 2015 at 11:17
  • @i3arnon I tried passing empty list. But that doesn't work Commented Jun 9, 2015 at 11:24
  • @user3561036 yes I am sure Commented Jun 9, 2015 at 11:25
  • @Dhanilan What do you mean? You just said in your question that you can set an empty list. Commented Jun 9, 2015 at 11:25

1 Answer 1

2

To Hazard a guess, it's because the "array" field in the database is null after the insert. You either need to make the initial value in the database an empty array, or you need to make it not-present. You can either:

  • use the [BsonIgnoreIfDefault] attribute on your list field to not store nulls,
  • Initialize your list field to an empty list to store an empty array

This can be reproduced in the shell very easily:

> db.so.insert({x:1, y: null})
> db.so.update({x:1}, {$push: { y: "funny" }})

This will error. However, if you remove y from the insertion or change it to an empty array, the update will succeed.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks. this might be working in shell. But doesn't work in C# api.
No, my point is that it doesn't work in the shell either. Did you make one of the changes I suggested in the C# API? Which one did you make? And could you indicate what your documents look like just after insert?
I just did both and both suggestions work... perhaps you could post what you are trying. Here is the gist of the second option (using scriptcs): gist.github.com/craiggwilson/f7145d6b00beaf9d0bdb
I think I know what might be your problem... You already have this data in the database. To do this update, you are going to need to fix the documents that have null values for this field.
hey craig...that works :). My case was though i passed empty List in constructor it was being over ridden when copying from my viewmodel. your gist helped me. Thanks a lot. I just added BsonIgnoreIfNull to the property.started to work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.