考虑以下类层次结构:
public abstract class Entity
{
public virtual int Id { get; private set; }
}
public class ConfiguredBlockEntity : Entity
{
public virtual ScheduledGreetingEntity ScheduledGreeting { get; set; }
}
public abstract class ConfiguredVariableEditableBlockEntity
: ConfiguredBlockEntity
{
public virtual VariableEditableBlockEntity TemplateBlock { get; set; }
}
public class ConfiguredPhoneNumberBlockEntity
: ConfiguredVariableEditableBlockEntity
{
public virtual string PhoneNumber { get; set; }
}
我正在使用Fluent NHibernate的自动功能。
这将创建以下表结构:
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";
此结果存在一些问题:
ConfiguredPhoneNumberBlockEntity
有一列是主键和一个基类的外键(列ConfiguredVariableEditableBlockId
。这看起来很奇怪,不符合我通常设计表格的方式。如果我手动设计了这个表,它会有一个Id
列是PK,而ConfiguredBlockId
列是FK。我可以通过流畅或自动化以某种方式更改它吗? ConfiguredVariableEditableBlockId
,但没有表ConfiguredVariableEditableBlock
,因为它是一个抽象基类,其属性已合并到ConfiguredPhoneNumberBlockEntity
表中。此列引用表ConfiguredBlockEntity
,因此应相应地命名。 如何以流畅或自动化方式解决此问题? 答案 0 :(得分:2)
继承表不需要额外的Id列,它永远不会单独读取或通过id读取。通常它与baseclass-table连接。因此FNH默认使用此设计。您可以使用FluentMappings强制执行您的设计,隐藏属性ID为Readonly(无值的额外工作)。
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");
}
}
编辑:或更一般的
class MyJoinedSubclassConvention : IJoinedSubclassConvention
{
public void Apply(IJoinedSubclassInstance instance)
{
Type basetype = instance.Extends;
while (basetype.IsAbstract)
{
basetype = basetype.BaseType;
}
instance.Key.Column(basetype.Name + "Id");
}
}