zoukankan      html  css  js  c++  java
  • NHibernate one-to-one

    NHibernate里面one-to-one有两种方式:主键关联和唯一外健关联

    主键关联:
    两个表拥有相同的主键字段,值相同的关联在一起。典型的应用是一个对象的属性太多,将常用的属性跟不常用的附加属性分开存放,或者按照业务分类存放、维 护,例如物料的通用属性、财务属性、采购属性、生产制造属性。因为表示的是同一个对象,所以它们的生命周期是相同的。但一般会有一个主从关系,因为通常我 们会将其中的一个主表跟对象直接映射,其它的做为附属。

    唯一外健关联:
    两个表拥有独立的主键字段(实体id),一个表用外键关联另外一个表。其实就是将一个one-to-many的表结构设计当作one-to-one的方式使用。
    拥有独立的实体id,通常意味着对象的生命周期是独立的,需要的时候可以建立起one-to-one的关系,分开之后仍独立存在。例如夫妻关系(假设一夫一妻制),士兵跟枪的关系(假设一个士兵只配备一支枪)。

    主键关联示例:
    <class name="BoxDao" table="CMS_BOX">
        <id name="BoxId" >
            <column name="BOX_ID" sql-type="NUMBER(8,0)" not-null="true"/>
            <generator class="assigned" />
        </id>
        <one-to-one name="WrapperParam" lazy="proxy" cascade="all" />
    </class>

    public class BoxDao
    {
        private int _boxId;
        private WrapperParamDao _wrapperParam;

        public BoxDao()
        {
        }

        public virtual int BoxId
        {
            get { return this._boxId; }
            set { this._boxId = value; }
        }

        public virtual WrapperParamDao WrapperParam
        {
            get { return this._wrapperParam; }
            set { this._wrapperParam = value; }
        }
    }

    <class name="WrapperParamDao" table="CMS_WRAPPER_PARAM">
        <id name="BoxId" >
            <column name="BOX_ID" sql-type="NUMBER(8,0)" not-null="true"/>
            <generator class="foreign">
                <param name="property">Box</param>
            </generator>
        </id>
        <one-to-one name="Box" constrained="true" cascade="none" />
    </class>

    public class WrapperParamDao
    {
        private int _boxId;
        private BoxDao _box;

        public WrapperParamDao()
        {
        }

        public virtual int BoxId
        {
            get { return this._boxId; }
            set { this._boxId = value; }
        }

        public virtual BoxDao Box
        {
            get { return this._box; }
            set { this._box = value; }
        }
    }

    WrapperParamDao的配置中,<generator class="foreign">指示NHibernate在保存的时候,通过Box属性获取BoxId的值。 constrained="true"相当于指定了one-to-one的关联方向,它会影响到Save()、Delete()操作的顺序。

    保存WrapperParamDao时需要确保Box属性的有效性,否则将无法获取BoxId值;同样保存BoxDao是要确保WrapperParam的属性值。如果是同时新增这两个对象,更需要注意:
    box.WrapperParam = wrapperParam;
    wrapperParam.Box = box;
    session.Save(box);
    如果<generator class="foreign">配置不当,或者保存时属性没有设置,将会报错"Unexpected row count: 0; expected: 1"之类:
    Unexpected row count: 0; expected: 1
    at NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(Int32 rowCount, IDbCommand statement)
    at NHibernate.Impl.NonBatchingBatcher.AddToBatch(IExpectation expectation)
    at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
    at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, ISessionImplementor session)
    at NHibernate.Impl.ScheduledUpdate.Execute()
    at NHibernate.Impl.SessionImpl.Execute(IExecutable executable)
    at NHibernate.Impl.SessionImpl.ExecuteAll(IList list)
    at NHibernate.Impl.SessionImpl.Execute()
    at NHibernate.Impl.SessionImpl.Flush()
    at NHibernate.Transaction.AdoTransaction.Commit()

    唯一外健关联:
    NHibernate文档中的例子:
    <many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>

    <one-to-one name="Employee" class="Employee" property-ref="Person"/>
    分类: NHibernate
  • 相关阅读:
    转:Metronic – 超赞!基于 Bootstrap 的响应式后台管理模板
    [km] 如何判断一个直播系统是否使用的是RTMP
    xshell5.0实现中键复制
    [转] 腾讯云直播OBS推流教程
    eclipse格式化代码快捷键失效
    JAVA注解@Interface基础知识
    MySQL按中文拼音排序
    Navicat连不上mysql8
    MySQL重置root密码
    CentOS7防火墙之firewalld
  • 原文地址:https://www.cnblogs.com/hyl8218/p/5626322.html
Copyright © 2011-2022 走看看