I'm having problems trying to save a new child object via breeze, my model boils down to this
Parent Foo has zero or more child objects of type bar ie Parent has a property of type ICollection called bars and the Bar object has a property of type Foo - its parent
I can fetch, update and insert new instances of "parent" Foo objects via Breeze - this is using the web api controller but I get a constraint violation when creating a new instance of Bar, setting its parent Foo (already in the cache) and calling save changes
I have code similar to this
var newBar = entityManager.createEntity("Bar");
newBar.Foo = existingFoo;
entityManager.saveChanges();
I've also tried adding the child to the parents collection eg existingFoo.bars.push(newBar);
and explicitly calling
entityManager.addEntity(newBar);
before calling save changes but the error is the same
Inspecting the JObject saveBundle passed to the controller I can see the new child bar object but I don't see any reference to the parent object
This is a simple one to many relationship which I think is supported? - I can see the relationship in the metadata which looks correct
The exception message looks like this
Entities in 'FooBarContext.Bars' participate in the 'Foo_Bars' relationship. 0 related 'Foo_Bar_Source' were found.
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\":\"true\",\"nullable\":\"true\"}],\"navigationProperty\":{\"name\":\"Children\",\"relationship\":\"Self.Bar_Parent\",\"fromRole\":\"Bar_Parent_Target\",\"toRole\":\"Bar_Parent_Source\"}},{\"name\":\"Bar\",\"key\":{\"propertyRef\":{\"name\":\"Id\"}},\"property\":[{\"name\":\"Id\",\"type\":\"Edm.Int32\",\"nullable\":\"false\",\"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\"}}],\"association\":{\"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\",\"association\":\"Self.Bar_Parent\",\"end\":[{\"role\":\"Bar_Parent_Source\",\"entitySet\":\"Bars\"},{\"role\":\"Bar_Parent_Target\",\"entitySet\":\"Foos\"}]}}}}"
Sample code:
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:
{"entities":[{"Id":-1,"Description":"bar desc","entityAspect":{"entityTypeName":"Bar:#BreezePlayground.Models","entityState":"Added","originalValuesMap":{},"autoGeneratedKey":{"propertyName":"Id","autoGeneratedKeyType":"Identity"}}}],"saveOptions":{"allowConcurrentSaves":false}}
The child object is inserted but the foreign key is not set
I'm assuming this is something to do with the ef mapping and generated metadata?
Update 2: Foreign Key Property Required?
I compared my code with the new Breeze SPA template ToDo app code which clearly works and the key difference I spotted in the generated metadata was that the ToDo app model exposes the parent object foreign key.
I added that to my simple Foo Bar model and was able to get the save of a child object to work - my understanding is that ef makes it optional to expose the foreign key in the model but it seems that is a requirement for Breeze in order to generate the correct metadata? - did I miss that in the docs somewhere?