I have a parent (Order) and child (OrderDetail) where Order already exists in the database and OrderDetail also exists in the database.
All I really want to do is add another OrderDetail record bound to the Order.
I have been down several paths and I'm not even sure what is the correct path.
Let's make some assumptions that navigations between these are already working.
I can $expand=OrderDetails fine and I can also Orders(1)/OrderDetails fine and do the reverse from OrderDetails.
Based on this Updating the Data Service, all I need to do is call AddRelatedObject and then Add the object to the OrderDetails collection.
// Add the new item with a link to the related Order
context.AddRelatedObject(order, "OrderDetails", newOrderDetail);
// Add the new order detail to the collection
order.Order_Details.Add(newOrderDetail);
newOrderDetail.Order = order;
Seems simple enough.
Yet when I execute context.SaveChanges(SaveChangesOptions.ReplaceOnUpdate) it will throw an error.
{"error":{"code":"","message":"No HTTP resource was found that matches the request URI 'http://localhost/Test/odata/Orders(1)/OrderDetails'.","innererror":{"message":"No routing convention was found to select an action for the OData path with template '~/entityset/key/navigation'.","type":"","stacktrace":""}}}
But if I navigate to the URL listed, it shows data.
Time for Fiddler.
In Fiddler, I can see this is a POST to the URL and not a GET.
Which it should be a POST but not to the URL listed.
The POST should have been to /odata/OrderDetails
Round 2
// Add the new item with a link to the related Order
context.AttachTo("OrderDetails", newOrderDetail);
// Add a link between Order and the new OrderDetail
context.AddLink(order, "OrderDetails", newOrderDetail);
// Add the new order detail to the collection
order.Order_Details.Add(newOrderDetail);
newOrderDetail.Order = order;
Still a POST with an error but the URL is slightly different and the json posted only has "/odata/OrderDetail(0)" it also now has "$ref".
{"error":{"code":"","message":"No HTTP resource was found that matches the request URI 'http://localhost/Test/odata/Orders(1)/OrderDetails/$ref'.","innererror":{"message":"No routing convention was found to select an action for the OData path with template '~/entityset/key/navigation/$ref'.","type":"","stacktrace":""}}}
Well a quick web search led me to this article Entity Relations in OData v4 Using ASP.NET Web API 2.2
This article says I need to add a "CreateRef" in the Orders controller.
I did create a "CreateRef" in the Orders controller and sure enough it gets called BUT the article assumes the OrderDetail exists in the database.
It is not posting the json OrderDetail object.
Round 3
// Add the new item with a link to the related Order
context.AttachTo("OrderDetails", newOrderDetail);
// Attach a link between Order and the new OrderDetail
context.AttachLink(order, "OrderDetails", newOrderDetail);
// Add the new order detail to the collection
order.Order_Details.Add(newOrderDetail);
newOrderDetail.Order = order;
Well this seems much better.
No error but it did not fully work.
It sent a PUT to the /odata/OrderDetails(0) and it did send the json OrderDetail object BUT this should have been a POST not a PUT.
I feel I am so close yet I can't seem to figure out how to get it to work properly.
Any ideas?