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 value
model.PackageItems[0].DeliverableID = 652
// Foreign key to existing Deliverable Entity
model.PackageItems[0].Deliverable =
null
;
// Navigation Property to existing Deliverable Entity
model.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
; }
}