提供以下结构,
MyBaseClass {
public int Id {get; private set;}
}
MySubclassWithDiscriminator : MyBaseClass {
}
MySubclass : MyBaseClass {
public string SomeThing {get; set;}
}
我如何使用Fluent NH正确映射这些,使用table-per-subclass和table-per-class-hierarchy?我已经尝试过自定义AutomappingConfiguration,但似乎是在圈子中进行:
public class AutomappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.Namespace.Contains("Entities");
}
public override bool IsDiscriminated(Type type)
{
// only classes with additional properties should be
// using the table-per-subclass strategy
if ((type.IsAssignableFrom(typeof(MyBaseClass)) ||
type.IsSubclassOf(typeof(MyBaseClass)) &&
type.GetProperties(BindingFlags.Public |
BindingFlags.FlattenHierarchy)
.Count() <= 1))
{
return true;
}
return false;
}
}
public class SubclassConvention : ISubclassConvention
{
public void Apply(ISubclassInstance instance)
{
// Use the short name of the type, not the full name
instance.DiscriminatorValue(instance.EntityType.Name);
}
}
在我的调查中,我认为在使用FNH时使用Discriminator是一个二元选择,而HBM可以同时拥有Discriminator列和子类。
答案 0 :(得分:0)
编辑 - 2011-05-12
我重写了这篇文章,试图解决詹姆斯格雷戈里的评论。
这是我想要实现的HBM:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class
xmlns="urn:nhibernate-mapping-2.2"
name="Mixed_Parent"
abstract="true"
table="`Mixed_Parent`">
<id name="Id" type="System.Int32">
<generator class="identity" />
</id>
<discriminator type="String">
<column name="discriminator" />
</discriminator>
<subclass
name="Mixed_TPCH_Child"
discriminator-value="Mixed_TPCH_Child" />
<subclass
name="Mixed_TPS_Child"
discriminator-value="Mixed_TPS_Child">
<join table="`Mixed_TPS_Child`" >
<key column="Id" />
<property name="Description" type="String">
<column name="Description" />
</property>
</join>
</subclass>
</class>
</hibernate-mapping>
所以,我所看到的是,生成的HBM是<joined-subclass>
或<subclass>
没有<join>
子元素,而不是两者的组合。我在这里错过了什么吗?
这是一个失败的测试,可以添加到SubclassPersistenceModelTests来说明:
namespace MixedTablePerSubclassWithTablePerClassHierarchy
{
public class Mixed_Parent
{
public virtual int Id { get; set; }
}
public class Mixed_TPCH_Child
{
}
public class Mixed_TPS_Child
{
public virtual string Description { get; set; }
}
public class Mixed_ParentMap : ClassMap<Mixed_Parent>
{
public Mixed_ParentMap()
{
Id(x => x.Id);
DiscriminateSubClassesOnColumn("discriminator");
}
}
public class Mixed_TPCH_ChildMap : SubclassMap<Mixed_TPCH_Child>
{ }
public class Mixed_TPS_ChildMap : SubclassMap<Mixed_TPS_Child>
{
public Mixed_TPS_ChildMap()
{
Map(x => x.Description);
}
}
}
[Test]
public void ShouldAllowMixedTablePerSubclassWithTablePerClassHierarchy()
{
var model = new PersistenceModel();
model.Add(
new MixedTablePerSubclassWithTablePerClassHierarchy
.Mixed_ParentMap());
model.Add(
new MixedTablePerSubclassWithTablePerClassHierarchy
.Mixed_TPCH_ChildMap()
);
model.Add(
new MixedTablePerSubclassWithTablePerClassHierarchy
.Mixed_TPS_ChildMap());
var classMapping = model.BuildMappings()
.First()
.Classes.First();
// WHAT SHOULD THIS NUMBER BE (0, 1 or 2)?
classMapping.Subclasses.Count().ShouldEqual(1);
classMapping
.Subclasses
.First()
.Type
.ShouldEqual(
typeof(
MixedTablePerSubclassWithTablePerClassHierarchy
.Mixed_TPS_Child)
); // WHICH OF THE CHILDREN WOULD BE FIRST?
}