如何在NHibernate中使用相同的列映射3个引用?

时间:2012-10-08 07:30:52

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping

我有以下Ticket类:

public class Ticket {
  public virtual int Id { get; set; }
  public virtual Type Type { get; set; }
  public virtual Status Status { get; set; }
  public virtual State State { get; set; }
}

使用以下映射映射到旧数据库中的表:

public TicketMap()
{
    Table("TICKET");
    LazyLoad();
    Id(x => x.Id)
        .GeneratedBy.TriggerIdentity()
        .Column("ID")
        .Access.Property()
        .Not.Nullable();
    References(x => x.Type)
        .Class<Type>()
        .Cascade.None()
        .LazyLoad()
        .Columns("TYPE_ID");
    References(x => x.Status)
        .Class<Status>()
        .Cascade.None()
        .Columns("STATUS_ID", "TYPE_ID");
    References(x => x.State)
        .Class<State>()
        .Cascade.None()
        .LazyLoad()
        .Columns("STATE_ID", "TYPE_ID");
}

问题在于,当我尝试使用状态和状态保存故障单时,NHibernate不知道要使用哪个TYPE_ID并且无法保存实体。

状态和状态类都有复合键(我知道这是一种不好的做法,但如上所述,它是遗留数据库,我无法创建代理键。)

我有办法让这个参考工作吗?

1 个答案:

答案 0 :(得分:0)

一种可能的方法是将这些属性设置为只读。在xml配置中(我知道xml映射是世界的)它看起来像这样(对于其他两种ref类型也是如此:Type,State):

<many-to-one name="Status" insert="false" update="false" >
  <column name="STATUS_ID" />
  <column name="TYPE_ID" />
</many-to-one>
...

然后创建受保护的人工属性

<property name="StatusId" column="STATUS_ID" insert="true" update="true" />
<property name="StateId" column="STATE_ID" /><!-- above insert and update attr are redundant -->
<property name="TypeId" column="TYPE_ID" />

这些属性应在Ticket实体上声明为protected。通过一些内部逻辑,可以根据选定的状态,状态或类型将它们设置为正确的值。

我们得到的是对查询引擎的完全访问权限,因为所有3种引用类型都可用于过滤。插入/更新也会起作用,因为NHibernate确切知道要使用哪个值。