NHibernate 复合键

Posted

技术标签:

【中文标题】NHibernate 复合键【英文标题】:NHibernate Composite Key 【发布时间】:2010-04-23 08:02:15 【问题描述】:

我创建了一个复合键,它正在工作,但理想情况下我希望在行类中直接单独的字段。

我目前的做法如下:

    private UserPrimaryKey _compositeKey;
    public virtual UserPrimaryKey CompositeKey
    
        get
        
            if (_compositeKey == null) _compositeKey = new UserPrimaryKey();
            return _compositeKey;
        
        set 
            if (_compositeKey == value) return;
            _compositeKey = value;
            Host = value.Host;
            UserAccount = value.User;
        
    
    public string Host  get; set; 
    public string UserAccount  get; set; 

我想知道是否有更好的方法来做到这一点?可能在 NHibernate 配置文件中。

我当前的配置文件如下:

<class name="TGS.mysql.DataBaseObjects.DataBasePrivilege,TGS.MySQL.DataBaseObjects" table="user">
 <composite-id name="CompositeKey" class="TGS.MySQL.DataBaseObjects.UserPrimaryKey, TGS.MySQL.DataBaseObjects">
  <key-property name="Host" column="Host" type="string" length="60" />
  <key-property name="User" column="User" type="string" length="16" />
 </composite-id>
</class>

【问题讨论】:

【参考方案1】:

您可以直接在您的类中创建属性...并将它们映射到:

<composite-id>
  <key-property name="Host"/>
  <key-property name="UserAccount"/>
</composite-id>

如果你这样做,你将不得不在你的类中覆盖 EqualsGetHashCode

【讨论】:

【参考方案2】:

我建议如下:

    private UserPrimaryKey _compositeKey;
    public virtual UserPrimaryKey CompositeKey
    
        get
        
            if (_compositeKey == null) _compositeKey = new UserPrimaryKey();
            return _compositeKey;
        
        set 
            if (_compositeKey == value) return;
            _compositeKey = value;
            Host = value.Host;
            UserAccount = value.User;
        
    
    public string Host
    
        get
        
            return CompositeKey.Host;
        
        set
        
            CompositeKey.Host = value;
        
    
    public string UserAccount
    
        get
        
            return CompositeKey.User;
        
        set
        
            CompositeKey.User = value;
        
    

这样你就不会重复数据,只返回/设置复合键内的数据。

【讨论】:

【参考方案3】:

我会尽可能避免使用复合键。将其替换为两列上的常规唯一约束:

<class name="DataBasePrivilege" table="user">
  <id name="id">
    <generator class="hilo">
      <param name="table">user_HiLo</param>
      <param name="max_lo">100</param>
    </generator>
  </id>
  <property name="Host" length="60" unique-key="user_host"/>
  <property name="User" length="16" unique-key="user_host"/>
</class>

(顺便说一句:在常见的情况下你不需要指定类型,如果它们与属性名匹配,你也不需要指定列名。这样可以让你的 xml 可读)

【讨论】:

不幸的是,该表是 MySQL 原生表(用于保存 MySQL 数据库用户的记录),因此我无法更改架构。如果不更改架构,这仍然可以工作吗?

以上是关于NHibernate 复合键的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Nhibernate 的 Linq 检索 Group By 实体或复合键

Fluent NHibernate 多对多映射,使用自动生成的 pk 而不是复合键

如何在 Fluent NHibernate 中将一对一关系映射为复合键的一部分

NHibernate - 左连接

Nhibernate/Hibernate、查找表和对象设计

Nhibernate/Hibernate、查找表和对象设计