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.
//// AssembleDbContext 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.