I'm trying to not go into too much detail but provide enough. If it helps I have a test project I can send you ...
In short what I am trying to do is create a 2 layer vertical inheritance.
Layer One
I have defined a PRODUCT model/table mapping with a discriminator column
var configuration =
new
MappingConfiguration<ProductEntity>();
configuration.HasProperty(x => x.ProductType)
.HasFieldName(
"_productType"
)
.WithDataAccessKind(DataAccessKind.ReadWrite)
.ToColumn(
"DeliverableType"
)
.IsNotNullable()
.HasColumnType(
"nvarchar"
)
.WithVariableLength(50);
//
// Identify the discriminator property
configuration.HasDiscriminator().ToColumn(
"ProductType"
);
"Deliverable" and "Package" model/tables are derived from this PRODUCT and mapped to define the value to be inserted into the discriminator field of the parent.
var configuration =
new
MappingConfiguration<ProductDeliverableEntity>();
//
// Identify the product type discriminator
configuration.HasDiscriminatorValue(
"SINGLE"
);
var configuration =
new
MappingConfiguration<ProductDeliverablePackageEntity>();
//
// Identify the product type discriminator
configuration.HasDiscriminatorValue(
"PKG"
);
"Deliverable" is further extended by a specific TYPE of deliverable. In our example we have a PRINT deliverable and a VIDEO deliverable which derive from the ProductDeliverableEntity above.
var configuration
new
MappingConfiguration<PrintProductDeliverableEntity> ();
//
// Identify the value to assign to the DeliverableType Discriminator column
configuration.HasDiscriminatorValue(
"PRINT"
);
var configuration
new
MappingConfiguration<VideoProductDeliverableEntity> ();
//
// Identify the value to assign to the Discriminator column
configuration.HasDiscriminatorValue(
"VIDEO"
);
In order to support this second tier of inheritance, I added the definition of it's own discriminator column to the ProductDeliverableEntity definition so that it could support the specific types of being derived.
var configuration =
new
MappingConfiguration<ProductDeliverableEntity>();
//
// Identify the value to assign to the ProductType Discriminator column
configuration.HasDiscriminatorValue(
"SINGLE"
);
//
// Identify the column which defines which TYPE this is (i.e. discriminator)
configuration.HasDiscriminator().ToColumn(
"DeliverableType"
);
When I attempt to add either of the specific Deliverable types (Video or Print) I am getting a Cannot insert a NULL value into the "DeliverableType" field.
//
// Assemble
DbContext ctx =
new
DbContext();
VideoProductDeliverableEntity video =
new
VideoProductDeliverableEntity();
PrintProductDeliverableEntity print =
new
PrintProductDeliverableEntity();
ProductDeliverablePackageEntity pkg =
new
ProductDeliverablePackageEntity();
video.ProductName =
"120 second greeting"
;
video.ProductSku =
"VDO-120-MPG"
;
video.VideoFormat =
"mpg"
;
//video.DeliverableType = "TESTCODE";
print.ProductName =
"Fringe Badge"
;
print.ProductSku =
"BDG-FRINGE-40"
;
print.Media =
"Badge"
;
print.Printer =
"DS40"
;
//print.DeliverableType = "TESTCODE";
pkg.Contents.Add(video);
pkg.Contents.Add(print);
pkg.ProductName =
"Video print"
;
pkg.ProductSku =
"VDOPRNT-001"
;
ctx.Add(video);
ctx.Add(print);
ctx.Add(pkg);
ctx.SaveChanges();
When I uncomment the lines where the DeliverableType is explicitly assigned, the test code completes running. What I have discovered however, is that the "VIDEO" and "PRINT" discriminator values are being inserted into the ProductType discriminator field instead of the DeliverableType, thus resulting in a NULL value being assigned to the DeliverableType (which is not allowed).
The discriminator value of "SINGLE" is never used at all. I am not sure if there is an issue that causes the discriminator to be passed all the way to the lowest level instead of the "next" or first level that defines a discriminator. This is a fundamental piece of our architecture decision-making so any help would be greatly appreciated.
I created a small test project that illustrates the issue if providing that would help I would be happy to forward that along.