I am attempting to add a new "DeliverablePackage" entity to my database. Each "DeliverablePackage" entity will contain references to one or more new (not currently existing) "DeliverablePackageItem" entities, so these "DeliverablePackageItem" entities need to be created at the same time as the "DeliverablePackage" entity itself. The request is being made to a WebAPI web service, so the model definition is being sent as JSON. (This example is a package with a single package item )
{ "Label": "PackageName", "SKU": "PRT-040601-01", "Description": "It's a test package", "PackageItems": [ { "DeliverableID": 652, "DeliverableQty": 1 } ]}
Using WebAPI this JSON is "hydrated" into my Domain models. This results in a "DeliverablePackage" model with a collection of "PackageItems" in a navigation property loaded with the details of the "DeliverablePackageItem" defined in the JSON.
[HttpPost]public void CreateDeliverablePackage([FromBody] DeliverablePackage model){ using (CatalogAdminDbCtx ctx = new CatalogAdminDbCtx()) { model = repo.ctx.AttachCopy<DeliverablePackage>(model); // changes state from "NotManaged" to "New" ctx.Add(model); ctx.SaveChanges(); }}
If I were to inspect the properties of the model reference at this time I would see something like ...
model.Label = "PackageName"model.SKU = "PRT-040601-01"model.Description = "It's a test package"model.ID = 0 // default valuemodel.PackageItems[0].DeliverableID = 652 // Foreign key to existing Deliverable Entitymodel.PackageItems[0].Deliverable = null; // Navigation Property to existing Deliverable Entitymodel.PackageItems[0].DeliverableQty = 1 // the number of Deliverables included in this item.model.PackageItems[0].PackageID = 0 // Foreign key to the DeliverablePackage that this DeliverablePackageItem is in.model.PackageItems[0].Package = null // Navigation property to the DeliverablePackage that this DeliverablePackageItem is in (obviously would be self-referencing if we were to populate it)In this example I am expecting a new "DeliverablePackage" to be added to the database as well as a new "DeliverablePackageItem" associated to the "DeliverablePackage" which will reference an existing "Deliverable" (ItemID). I am instead getting a "The INSERT statement conflicted with the FOREIGN KEY constraint" ERROR because the context is attempting to insert the new "DeliverablePackageItem" but not associate it with the parent "DeliverablePackage".
So, it appears that the problem is that the insertion of the "DeliverablePackage" is not associating it's newly generated ID with it's "DeliverablePackageItem" as I would have expected (still learning).
Is there some way for the ORM to apply this association or do I have to parse through and find it manually?
Here are the model definitions to help illustrate how things are structured and associated.
public class Deliverable : ModelBase, ISingleID{ public Int64 ID { get; set; } public String Label { get; set; } public String Description { get; set; }}public class DeliverablePackage : ModelBase, ISingleID{ public Int64 ID { get; set; } public String Label { get; set; } public String SKU { get; set; } public String Description { get; set; } public IList<DeliverablePackageItem> DeliverableItems { get; set; }}public class DeliverablePackageItem : ModelBase{ public Int16 DeliverableQty { get; set; } // // foreign key and navigation property public Int64 PackageID { get; set; } public DeliverablePackage Package { get; set; } // // foreign key and navigation property public Int64 DeliverableID { get; set; } public Deliverable Deliverable { get; set; }}