Published
Monday, August 27, 2007 4:01 PM
by
mtaulty
In order to look at the next keywords that I wanted to look at (IS OF, OFTYPE, TREAT) I need to introduce some kind of inheritance. I modified my Shippers table in Northwind to try and model inheritance using the table-per-hierarchy model (it's not the only way that you can model inheritance in EF) where you store all the "objects" into a single table and have some discriminating column so that you can tell them apart.
I modified the Shippers table so it now has 2 extra columns on it;
alter table shippers
add ShipperType int not null default(0)
alter table shippers
add ExtraInformation nvarchar(50) null
and set the data so it looks like this;
1 Speedy Express (503) 555-9831 0 NULL
2 United Package (503) 555-3199 0 NULL
3 Federal Shipping (503) 555-9931 1 Some Extra Information
And used egmgen.exe to refresh my northwind.csdl, northind.ssdl, northwind.msl files. I then need to edit them to introduce the inheritance relationship.
So, we have rows 1 and 2 which are regular old Shippers and we've got row 3 which is what I'll be calling a FancyShipper. Now, I then went off and spent about 30 minutes trying to hack my mapping files and I kept coming up with an error that read something but not exactly like this;
ERROR (3020): Problem in Mapping Fragment(s) starting at line(s) {81, 23}: Entity data will be lost when storing in table Shippers: The rows in table Shippers for when [Shippers.ShipperType = 0] and the rows in this table for when [Shippers.ShipperType = 0] are disjoint but the corresponding entities in set(s) (Shippers, FancyShippers) are not necessarily disjoint.
Now, I hadn't the foggiest clue what this was all about but in the end I figured out what it was I was trying to do. In my EDM I'd constructed two EntitySets named Shippers and FancyShippers.
NO, NO, NO!
This is wrong, what I want is one EntitySet called Shippers and that EntitySet contains both Shippers and FancyShippers. If you've got derived types like this and you put them into multiple EntitySets then I think you'll see the error above.
So, what did I actually change to make this work.
northwind.CSDL file
Simply added a new entity type;
<EntityType Name="FancyShippers" BaseType="northwind.Shippers">
<Property Name="ExtraInformation" Type="String" Nullable="true" MaxLength="50"/>
</EntityType>
northwind.SSDL file
No changes necessary, this is all conceptual stuff that the store doesn't care about.
northwind.MSL file
Changed the EntitySetMapping for Shippers to look like this;
<EntitySetMapping Name="Shippers" StoreEntitySet="Shippers">
<EntityTypeMapping TypeName="northwind.Shippers">
<MappingFragment StoreEntitySet="Shippers">
<ScalarProperty Name="ShipperID" ColumnName="ShipperID" />
<ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
<ScalarProperty Name="Phone" ColumnName="Phone" />
<Condition ColumnName="ShipperType" Value="0"/>
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="northwind.FancyShippers">
<MappingFragment StoreEntitySet="Shippers">
<ScalarProperty Name="ShipperID" ColumnName="ShipperID" />
<ScalarProperty Name="CompanyName" ColumnName="CompanyName" />
<ScalarProperty Name="Phone" ColumnName="Phone" />
<ScalarProperty Name="ExtraInformation" ColumnName="ExtraInformation" />
<Condition ColumnName="ShipperType" Value="1"/>
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
and with that in place I made sure that my new files validated using the (edmgen.exe /mode:validateartifacts /incsdl:northwind.csdl /inssdl:northwind.ssdl /inmsl:northwind.msl) command line and everything is fine and I'm ready to go with some limited inheritance stuff.