ahs*_*ele 6 nhibernate nhibernate-mapping fluent-nhibernate fluent-nhibernate-mapping
我正在使用一个棕色数据库,我正在尝试配置一个子类映射,该映射使用除指定id之外的列连接到其子类.该login
表有一个主键列login_sk
,我想用它作为它的id.它通过一个login_cust_id
列连接到两个表(为了使相邻表中相应列的命名方式更加有趣).如果我设置login_cust_id
为UserMap的id,它会按预期加入其子类.我希望显而易见的原因是我不想将login_cust_id
其用作我的User对象的id.
public class UserMap : ClassMap<IUser>
{
public UserMap()
{
Table("login");
Id(x => x.Id).Column("login_sk"); // want to setup map like this
// if used instead this works for subclass joining / mapping
// Id(x => x.Id).Column("login_cust_id");
// would prefer to only reference login_cust_id for subclass mapping
}
}
public class CustomerUserMap : SubclassMap<CustomerUser>
{
public CustomerUserMap()
{
Table("customer");
Map(c => c.DisplayName, "cust_mail_name");
Map(c => c.RecordChangeName, "cust_lookup_name");
KeyColumn("cust_id");
}
}
public class EntityUserMap : SubclassMap<EntityUser>
{
public EntityUserMap()
{
Table("entity");
Map(c => c.DisplayName, "entity_name");
KeyColumn("entity_id");
}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的只是login_cust_id
在加入子类时使用列.是否有一个流畅的映射设置,允许我指定这个?如果没有流畅的映射,那么常规的NHibernate XML映射会起作用吗?我甚至不想映射列,只在可能的情况下使用它来加入.如果它有帮助,则有一个潜在的鉴别器列login_holder_type
,指示要加入的表.
它确实发生在我设置,IClassConvention
但在通过后IClassInstance
我无法确定任何可以帮助我的设置.
public class UserIdConvention : IClassConvention, IClassConventionAcceptance
{
public void Apply(IClassInstance instance)
{
// do something awesome with instance.Subclasses to
// specify the use of login_cust_id for subclass joining...
}
public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
{
criteria.Expect(x => typeof(User).Equals(x.EntityType));
}
}
Run Code Online (Sandbox Code Playgroud)
传递的实例缺少一个填充的Subclasses集合,这使我找到了一个更具体的检查器IParentInspector
.不幸的是,Fluent NHibernate似乎没有相应的实现IParentInstance
,IParentConvention
或者IParentConventionAcceptance
像它那样IJoinedSubclassInspector
.虽然我可以在我做之前实现自己,但我想确保我没有咆哮错误的树.
是否可以进行这种子类id调整?我在地图或Fluent NHibernate Conventions命名空间中遗漏了哪些东西?如何使用与父ID不同的列/属性映射到已连接的子类?
我能够想到三种可能的解决方案来解决您的问题,请参阅下面的我的发现。
我最初的想法是使用基于鉴别器的映射来对继承进行建模,每个子类都包含带有属性引用的连接,即
<class name="IUser" abstract="true" table="login">
<id name="Id" column="login_sk">
<generator class="identity"/>
</id>
<discriminator column="login_holder_type" not-null="true" type="System.String"/>
<subclass name="CustomerUser" discriminator-value="Customer">
<join table="customer" >
<key column="cust_id" property-ref="login_cust_id" />
<property name="DisplayName" column="cust_mail_name"/>
<property name="RecordChangeName" column="cust_lookup_name" />
</join>
</subclass>
<subclass name="EntityUser" discriminator-value="Entity">
<join table="entity" >
<key column="entity_id" property-ref="login_cust_id" />
<property name="CompanyName"/>
</join>
</subclass>
</class>
Run Code Online (Sandbox Code Playgroud)
不幸的是,目前 Hibernate 支持此功能,但 NHibernate 不支持。请参阅此处和此处查看未偿还的门票。一些工作致力于添加此功能,可以在github 上的此分支上看到。
另一种选择是仍然使用基于鉴别器的映射,但many-to-one
在每个子类中使用映射,这将允许您使用属性引用连接外键。这样做的缺点是需要为客户和实体表中的所有属性提供单独的类,但这是一个可行的解决方案。
<class name="IUser" abstract="true" table="login">
<id name="Id" column="login_sk">
<generator class="identity"/>
</id>
<discriminator column="login_holder_type" not-null="true" type="System.String"/>
<subclass name="CustomerUser" discriminator-value="Customer">
<many-to-one name="CustomerProps" property-ref="login_cust_id" />
</subclass>
<subclass name="EntityUser" discriminator-value="entity">
<many-to-one name="EntityProps" property-ref="login_cust_id" />
</subclass>
</class>
<class name="CustomerProps" Table="customer" >
<id name="Id" column="cust_id">
<generator class="assigned"/>
</id>
<property name="DisplayName" column="cust_mail_name"/>
<property name="RecordChangeName" column="cust_lookup_name" />
</class>
<class name="EntityProps" Table="entity" >
<id name="Id" column="entity_id">
<generator class="assigned"/>
</id>
<property name="CompanyName"/>
</class>
Run Code Online (Sandbox Code Playgroud)
最后一个选项是在数据库中为包含 login_sk 字段的客户和实体表创建可更新视图。然后您可以Join
在每个子类中使用,因为您不需要property-ref
.
<class name="IUser" abstract="true" table="login">
<id name="Id" column="login_sk">
<generator class="identity"/>
</id>
<discriminator column="login_holder_type" not-null="true" type="System.String"/>
<subclass name="CustomerUser" discriminator-value="Customer">
<join table="customerView" >
<key column="login_sk" />
<property name="DisplayName" column="cust_mail_name"/>
<property name="RecordChangeName" column="cust_lookup_name" />
</join>
</subclass>
<subclass name="EntityUser" discriminator-value="Entity">
<join table="entityView" >
<key column="login_sk" />
<property name="CompanyName"/>
</join>
</subclass>
</class>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1936 次 |
最近记录: |