Wrong column name in table per subclass strategy with abstract class in hierarchy
Consider the following class hierarchy:
public abstract class Entity
{
public virtual int Id { get; private set; }
}
public class ConfiguredBlockEntity : Entity
{
public virtual ScheduledGreetingEntity ScheduledGreeting { get; set; }
}
public abstract class ConfiguredVariableEditableBlockEnt开发者_JAVA技巧ity
: ConfiguredBlockEntity
{
public virtual VariableEditableBlockEntity TemplateBlock { get; set; }
}
public class ConfiguredPhoneNumberBlockEntity
: ConfiguredVariableEditableBlockEntity
{
public virtual string PhoneNumber { get; set; }
}
I am using the automapping feature of Fluent NHibernate.
This creates the following table structure:create table "BlockEntity" (
Id INT IDENTITY NOT NULL,
ExecutionOrder INT null,
Name NVARCHAR(255) null,
BlockType NVARCHAR(255) null,
GreetingId INT null,
primary key (Id)
);
create table "ConfiguredBlockEntity" (
Id INT IDENTITY NOT NULL,
ScheduledGreetingId INT null,
primary key (Id)
);
create table ConfiguredPhoneNumberBlockEntity (
ConfiguredVariableEditableBlockId INT not null,
PhoneNumber NVARCHAR(255) null,
VariableEditableBlockId INT null,
primary key (ConfiguredVariableEditableBlockId)
);
alter table ConfiguredPhoneNumberBlockEntity
add constraint FK87F9EFC9BB9A4B52
foreign key (ConfiguredVariableEditableBlockId)
references "ConfiguredBlockEntity";
There are some problems with this result:
- The table
ConfiguredPhoneNumberBlockEntity
has one column that is primary key and foreign key to the base class in one (columnConfiguredVariableEditableBlockId
. This looks strange and doesn't conform to how I normally design my tables. If I would have designed the table by hand, it would have anId
column that is the PK and anConfiguredBlockId
columnt that is the FK. Can I change this somehow with fluent or automapping? - The PK/FK column is named
ConfiguredVariableEditableBlockId
, but there exists no tableConfiguredVariableEditableBlock
, because it was an abstract base class and its property has been incorporated intoConfiguredPhoneNumberBlockEntity
table. This column references the tableConfiguredBlockEntity
and thus should be named accordingly. How to fix this in fluent or automapping?
an inheritance table doesnt need an extra Id column, its never read alone or by id. Normally its joined with the baseclass-table. Therefor FNH defaults to this design. You can enforce your design for example with FluentMappings with a hidden Property Id as Readonly (additional work for no value).
class MyJoinedSubclassConvention : IJoinedSubclassConvention, IJoinedSubclassConventionAcceptance { public void Accept(IAcceptanceCriteria<IJoinedSubclassInspector> criteria) { criteria.Expect(x => x.Name == "ConfiguredPhoneNumberBlockEntity"); } public void Apply(IJoinedSubclassInstance instance) { instance.Key.Column("baseclassId"); } }
Edit: or more general
class MyJoinedSubclassConvention : IJoinedSubclassConvention
{
public void Apply(IJoinedSubclassInstance instance)
{
Type basetype = instance.Extends;
while (basetype.IsAbstract)
{
basetype = basetype.BaseType;
}
instance.Key.Column(basetype.Name + "Id");
}
}
精彩评论