I'm having trouble trying to save a new child through the breeze, my model comes down to this
Parent Foo has zero or more children of type bar, i.e. Parent has a property of type ICollection, called bars, and a Bar object has a property of type Foo - its parent
I can extract, update and insert new instances of the βparentβ Foo objects via Breeze - this uses the web api controller, but I get a violation of the restrictions when creating a new Bar instance, setting its parent Foo (already in the cache) and causing save changes
I have code similar to this
var newBar = entityManager.createEntity("Bar"); newBar.Foo = existingFoo; entityManager.saveChanges();
I also tried adding a child to my parents collection, for example existingFoo.bars.push (newBar);
and explicitly calling entityManager.addEntity (newBar);
before calling save changes, but the error is the same
Checking that the JObject saveBundle is passed to the controller, I see the new object of the child bar, but I do not see the reference to the parent object
Is it a simple-to-many relationship that I think is supported? - I see a metadata relationship that looks right
The exception message is as follows
Entities in 'FooBarContext.Bars' participate in the relation 'Foo_Bars'. 0 related "Foo_Bar_Source".
What am I doing wrong?
Update 1: Metadata generated by the controller:
"{\" schema \ ": {\" namespace \ ": \" BreezePlayground.Models \ "\" Alias ββ\ ": \" Self \ ", \" d4p1: UseStrongSpatialTypes \ ": \" false \ ", \ "xmlns: d4p1 \": \ " http://schemas.microsoft.com/ado/2009/02/edm/annotation \", \ "xmlns \": \ " http://schemas.microsoft.com/ado / 2009/11 / edm \ ", \" cSpaceOSpaceMapping \ ": \" [[\\ "BreezePlayground.Models.Foo \\", \\ "BreezePlayground.Models.Foo \\"], [\\ "BreezePlayground. Models.Bar \\ "\\" BreezePlayground.Models.Bar \\ "]] \", \ "EntityType \": [{\ "name \": \ "Foo \" \ "key \": {\ " propertyRef \ ": {\" name \ ": \" Id \ "}}, \" property \ ": [{\" name \ ": \" Id \ ", \" Type \ ": \" Edm.Int32 \ ", \" nullable \ ": \" false \ ", \" d4p1: StoreGeneratedPattern \ ": \" Identity \ "}, {\" name \ ": \" Name \ ", \" Type \ ": \ "Edm.String \", \ "fixedLength \": \ "false \", \ "MAXLENGTH \": \ "Max \", \ "Unicode \": \ " stan \ ", \" nullable \ ": \" true \ "}], \" navigationProperty \ ": {\" name \ ": \" Children \ ", \" relationships \ ": \" Self.Bar_Parent \ " , \ "fromRole \": \ "Bar_Parent_Target \", \ "toRole \": \ "Bar_Parent_Source \"}}, {\ "name \": \ "Bar \", \ "key \": {\ "propertyRef \ ": {\" name \ ": \" Id \ "}}, \" property \ ": [{\" name \ ": \" Id \ ", \" type \ ": \" EDM. Int 32 \ ", \" nullable \ ": \" fake \ ", \" d4p1: StoreGeneratedPattern \ ": \" Identity \ "}, {\" Name \ ": \" Description \ ", \" Type \ " : \ "Edm.String \", \ "fixedLength \": \ "false \", \ "MAXLENGTH \": \ "Max \", \ "Unicode \": \ "true \", \ "nullable \" : \ "true \"}], \ "navigationProperty \": {\ "name \": \ "parent \", \ "relationship \": \ "Self.Bar_Parent \", \ "fromRole \": \ " Bar_Parent_Source \ ", \" toRole \ ": \" Bar_Parent_Target \ "}}], \" union \ ": {\" name \ ": \" Bar_Parent \ ", \" end \ ": [{\" role \ ": \" Bar_Parent_Source \ ", \" Type \ ": \" Edm.Self.Bar \ ", \" multiplicity \ ": \" * \ "}, {\" role \ ": \" Bar_Parent_Target \ ", \ "type \": \ "Edm.Self.Foo \", \ "multiplicity \": \ "0..1 \"}]}, \ "EntityContainer \": {\ "name \": \ "FooBarContext \ ", \" EntitySet \ ": [{\ "name \": \ "Foos \", \ "EntityType \": \ "self.foo \"}, {\ "name \": \ "Bars \", \ "EntityType \": \ " Self.Bar \ "}], \" associationSet \ ": {\" name \ ": \" Bar_Parent \ ", \" associations \ ": \" Self.Bar_Parent \ ", \" end \ ": [{\ "role \": \ "Bar_Parent_Source \", \ "EntitySet \": \ "Bars \"}, {\ "role \": \ "Bar_Parent_Target \", \ "EntitySet \": \ "Foos \"}] }}}} "
Code example:
var managerInsert = new breeze.EntityManager("/api/FooBar"); managerInsert.fetchMetadata().then(function () { managerInsert.fetchEntityByKey('Foo', 1, false) .then(function (data) { var child = managerInsert.createEntity('Bar'); child.Parent(data.entity); child.Description("bar desc"); managerInsert.saveChanges().then(function () { return true; }) .fail(function () { alert('save failed'); }); }) .fail(function (data) { alert('fail'); }); });
generated request payload:
{"entity": [{"Id": - 1, "Description": "bar desc", "entityAspect": {"entityTypeName": "Bar: # BreezePlayground.Models", "entityState": "Added", " originalValuesMap ": {}," autoGeneratedKey ": {" PropertyName ":" Identifier "," autoGeneratedKeyType ":" identity "}}}]," SaveOptions ": {" allowConcurrentSaves ": false}}
A child object was entered, but the foreign key is not set
I assume this is due to the display of ef and the generated metadata?
Update 2: Do you need a foreign key property?
I compared my code with the new Breeze SPA code template, which obviously works, and the key difference I found in the generated metadata was that the ToDo application model provides the foreign key of the parent object.
I added this to my simple Foo Bar model and was able to get the child to be saved for work - I understand that ef does not have to expose the foreign key in the model, but does it seem like a requirement for Breeze to generate the correct metadata? βDid I miss this in the documents somewhere?β