Here's a sample project I created to demonstrate some of the issues:
https://docs.google.com/open?id=0B_rcns ... I2NDIyMDgy
In this example, 3 types derive from an abstract Message base type: Fax, Letter and Email.
I'm using a table-per-hierarchy mapping, and most of the problems are related to mapping these types to the same table.
The generated schema looks like this:
Code: Select all
CREATE TABLE dbo.Messages ( Id VARCHAR(MAX) NOT NULL IDENTITY, Created DATETIME2 NOT NULL, Subject VARCHAR(255) NOT NULL, Body VARCHAR(MAX) NOT NULL, Type VARCHAR(1) NOT NULL, CONSTRAINT PK_Messages PRIMARY KEY (Id) )
The Letter and Email types both have a Subject property, and these are mapped to the same column. Both are Nullable=False.
The column is generated as VARCHAR(255) NOT NULL, which is incorrect - it won't work, because the Fax type doesn't have a Subject property.
The Subject properties on Letter and Email are not nullable, and for those two entity types, the generated mappings are correct, in that we do want NH to prevent inserting NULL-values for that property, for those two types.
But the constraint cannot be enforced at the schema-level, as this makes it impossible to insert a Fax entity - which will always violate the NOT NULL constraint, as it does not have this property.
In other words, the Subject column should be generated as nullable - even if entities that do have this property should be mapped as not-nullable.
The Fax.Message, Letter.Text and Email.HTML properties are all mapped to the same column: Body.
One of these properties, Letter.Text, are flagged as Column.Unicode=True.
But the generated schema is VARCHAR(MAX), not NVARCHAR(MAX).
I think the problem here is really more of a general user-interface problem than anything else. ED does not seem to have an awareness of multiple properties mapping to the same column.
To use a simpler example, take Letter.Subject and Email.Subject - if you set the Column.Unicode property on either of those, it does not propagate to the other, although these are actually mapping to the same column.
Bottom line, if any property is mapped to the same column, setting any of the Column-settings on the model, ought to propagate to the Column-settings of other properties mapped to the same physical column.
I believe the second problem can be solved most simply at the user-interface level, since, presumably, you already have some logic in the schema-generator that enables it to "survive" conflicting column-settings, and still generate valid schema.
Ideally, you should not be permitted to make conflicts - at the very least, these should report as conflicts when you validate the model.
But ideally, the user-interface should not let you create conflicts, by propagating any changes made to Column-settings to the relevant Column-settings of properties, when they overlap at the schema-level.
If implemented this way, there are two important cases to take into account: adding a new property that overlaps with another existing property; and changing the Name in the Column-settings of an existing property, causing it to overlap with another existing property. In both cases, the Column-settings would overwrite the Column-settings of other properties already mapped, which is probably not what the end-user wants.
Assuming that ED would help you keep the Column-settings of any other existing overlapping properties consistent, you can safely copy the Column-settings from any of those - it doesn't matter which one.
The important point here, is you don't want a new property (or a Column.Name change) to overrule already existing Column-settings of any overlapping properties - rather, you want the pre-existing Column-settings to be "imported" to the new (or updated) column from an existing one. (after doing so, it is safe to propagate any further changes to the Column-settings from the new/updated property to the rest of the model.)
One last important thing to note, is that this behavior should apply only to table-per-hierarchy mappings - it must not apply to other types of inheritance-mappings, since those do not result in overlapping column-mappings.