composite key

本文介绍了如何在NHibernate中实现复合主键,并通过具体的代码示例展示了复合主键的定义、配置及使用方法,包括增删查操作。

CompositeKey的实现
 CompositeKey主键的实现。数据库中的一个表如果是组合主键,那么在使用

NHibernate是会有一点麻烦,不说了,用代码例子说话:
 1:准备工作,在Oracle中建立表结构,下面的建表的SQL语句(可以利用Toad For

Oracle)
 CREATE TABLE ROBOT_TRACKING
(
  LUNGUID     VARCHAR2(9 BYTE)                  NOT NULL,
  POS         VARCHAR2(2 BYTE)                  NOT NULL,
  ACT         VARCHAR2(2 BYTE)                  NOT NULL,
  TIMESTAMPS  DATE                              NOT NULL,
  TOC         DATE                              DEFAULT sysdate
);
CREATE UNIQUE INDEX ROBOT_TRACKING_PK ON ROBOT_TRACKING
(LUNGUID, ACT);
ALTER TABLE ROBOT_TRACKING ADD (
  CONSTRAINT ROBOT_TRACKING_PK
 PRIMARY KEY
 (LUNGUID, ACT)
    USING INDEX )
 
 2:准备数据表对象的数据实体,这一步是关键。还是用代码说话:
using System;
using System.Collections.Generic;
using System.Collections;

namespace OKEC.Sample.NHibernate.NHibernateTest
{
    public partial class RobotTracking
    {

        public override bool Equals(object obj)
        {
            if ((obj == this))
            {
                return true;
            }
            if (((obj == null)
                        || (obj.GetType() != this.GetType())))
            {
                return false;
            }
            RobotTracking test = obj as RobotTracking;
            return (Id.Equals(test.Id));
        }
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
        private System.DateTime _tIMESTAMPS;

        private System.DateTime _tOC;

        public RobotTracking()
        {
            this._idPK = new RobotTrackingPK();
        }

        public RobotTracking(string lunguid, string act)
        {
            this._idPK = new RobotTrackingPK();
            this._idPK.LUNGUID = lunguid;
            this._idPK .ACT = act;
            this.lunguId  = lunguid;
            this.act  = act;
            
        }
        
        private string _pOS;

        private string lunguId;

        private string act;
        public string ACT
        {
            get
            {
                return act;
            }
            set
            {
                this.Id.ACT = value;
                act = value;
            }
        }

        public override string ToString()
        {
            return string.Format("RobotTracking:{0} {1} {2} {3}

{4}",lunguId,act,_pOS ,_tIMESTAMPS ,_tOC );
        }

        public string LUNGUID
        {
            get
            {
                return lunguId;
            }
            set
            {
                this.Id.LUNGUID = value;
                lunguId = value;
            }
        }
     
        private RobotTrackingPK _idPK;

        public virtual System.DateTime TIMESTAMPS
        {
            get
            {
                return this._tIMESTAMPS;
            }
            set
            {
                this._tIMESTAMPS = value;
            }
        }

        public virtual System.DateTime TOC
        {
            get
            {
                return this._tOC;
            }
            set
            {
                this._tOC = value;
            }
        }

        public virtual string POS
        {
            get
            {
                return this._pOS;
            }
            set
            {
                this._pOS = value;
            }
        }

        public virtual RobotTrackingPK Id
        {
            get
            {
                return this._idPK;
            }
            set
            {
                this._idPK = value;
            }
        }

        [Serializable]
        public partial class RobotTrackingPK
        {
            private string _aCT;

            private string _lUNGUID;

            public virtual string ACT
            {
                get
                {
                    return this._aCT;
                }
                set
                {
                    this._aCT = value;
                }
            }

            public virtual string LUNGUID
            {
                get
                {
                    return this._lUNGUID;
                }
                set
                {
                    this._lUNGUID = value;
                }
            }

            public override string ToString()
            {
                return String.Join(":", new string[] {
                        this._aCT.ToString(),
                        this._lUNGUID.ToString()});
            }

            public override bool Equals(object obj)
            {
                if ((obj == this))
                {
                    return true;
                }
                if (((obj == null)
                            || (obj.GetType() != this.GetType())))
                {
                    return false;
                }
                RobotTrackingPK test = ((RobotTrackingPK)(obj));
                return (((_aCT == test._aCT)
                            || ((_aCT != null)
                            && _aCT.Equals(test._aCT)))
                            && ((_lUNGUID == test._lUNGUID)
                            || ((_lUNGUID != null)
                            && _lUNGUID.Equals(test._lUNGUID))));
            }

            public override int GetHashCode()
            {
                return XorHelper(_aCT.GetHashCode(), _lUNGUID.GetHashCode());
            }

            private int XorHelper(int left, int right)
            {
                return left ^ right;
            }
        }
    }
}

对上面代码的一些说明:
 将组合键设置为数据实体(也就是类RobotTracking)的内嵌类,这一步非常关键。我

试过,如果不是内嵌类的话,后面的代码就编译不了。例外实体类必须重载Equals()方法,

同时最好也重载GetHash()方法。还有一点需要指出的是组合键的类必须是[Serializable]属

性。建立好以后。
 3:对表RobotTrakcing的配置文件(RobotTracking.hbm.xml)文件,这个文件可以通

过CodeSmith生成,但是需要说明的我从网上下载的CodeSmith的NHibernate模版生成的文件不

能直接使用,需要修改。下面是配置文件,继续用代码说话。

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="OKEC.Sample.NHibernate.NHibernateTest.RobotTracking,NHibernateTest" 

table="ROBOT_TRACKING" lazy="false">
    <composite-id>
      <key-property  name="LUNGUID"  type="String">
        <column name="LUNGUID" length="9"/>
      </key-property>
      <key-property name="ACT" type="String">
        <column name="ACT" length="2"/>
      </key-property>
    </composite-id>

    <!--
      <id name="Id" type="String" unsaved-value="null">
   <column name="LUNGUID" length="9" sql-type="VARCHAR2" not-

null="true" index="ROBOT_TRACKING_PK"/>
   <column name="ACT" length="2" sql-type="VARCHAR2" not-

null="true" index="ROBOT_TRACKING_PK"/>
   <generator class="native" />
  </id>
-->


    <property name="POS" type="String">
   <column name="POS" length="2" sql-type="VARCHAR2" not-

null="true"/>
  </property>
  <property name="TIMESTAMPS" type="DateTime">
   <column name="TIMESTAMPS" sql-type="DATE" not-null="true"/>
  </property>
  <property name="TOC" type="DateTime">
   <column name="TOC" sql-type="DATE" not-null="false"/>
  </property>
 </class>
</hibernate-mapping>

配置文件的关键点在与
    <composite-id>
      <key-property  name="LUNGUID"  type="String">
        <column name="LUNGUID" length="9"/>
      </key-property>
      <key-property name="ACT" type="String">
        <column name="ACT" length="2"/>
      </key-property>
    </composite-id>
数据库中的主键对应,和数据实体类中的RobotTrackingPK类的字段对应。

 4:然后是整个使用NHibernate的配置,用代码说话:
<?xml version="1.0" encoding="utf-8"?>
<!-- 
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in

hibernate.cfg.xml and change it 
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.OracleClient.dll provider for Oracle from MS -->
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory name="NHibernate.Test">
  <property

name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
  <property name="connection.connection_string">
   User ID=Soctt;Password=tiger;Data Source=localHost
  </property>
  <property name="show_sql">false</property>
  <property

name="dialect">NHibernate.Dialect.OracleDialect</property>
    <mapping assembly="NHibernateTest" />  
  </session-factory>
</hibernate-configuration>

准备好了上面的内容后,就可以开始使用了
需要在工程中引用下列DLL
Common.Logging.DLL
Common.Logging.Log4Net.DLL
logNet4.DLL
NHibernate.DLL
Iesi.Collections.DLL
用代码说话:
using System;
using System.Collections;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Expression;

namespace OKEC.Sample.NHibernate.NHibernateTest
{
 class ClientApp
 {
  static void main(string[] args)
  {
    //得到NHibernate的配置
                Configuration cfg = new Configuration();
                cfg.Configure("Oracle.cfg.xml");

    ISessionFactory factory = cfg.BuildSessionFactory

();
    ISession session = factory.OpenSession();
    ITransaction transaction =

session.BeginTransaction();
                RobotTracking robotTracking ;

                     robotTracking = new RobotTracking(string.Concat("09060000",

i.ToString()), "US");
                    robotTracking.ACT = "US";
                    robotTracking.POS = "R2";
                    robotTracking.TIMESTAMPS = DateTime.Now;
                    robotTracking.TOC = DateTime.Now;
   //判断对应的数据是否存在
                    object obj= session.Get(typeof(RobotTracking), robotTracking);
                     //不存在进行插入操作
   if (obj == null)
                        session.Save(robotTracking);
   //存在进行删除操作
                    else
                        session.Delete(robotTracking);
     // commit all of the changes to the DB and

close the ISession
    transaction.Commit();
    session.Close();

    // open another session to retrieve the just

inserted user
    session = factory.OpenSession();

                //查询操作
               // IQuery query = session.CreateQuery("from RobotTracking where"+"

robotTracking.LUNGUID="+"090600005"+"");
                string lunguid = "090600001";
                string act="R3";
                string where = " where lunguid >= '" + lunguid +"' and

act<>'"+act+"'" ;

                IQuery query = session.CreateQuery("from RobotTracking "+where );
                IList<RobotTracking> list = query.List<RobotTracking>();
                foreach (RobotTracking  tracking in list )
                {
                    Console.WriteLine(tracking.ToString());
                }
                ICriteria creieria =  session.CreateCriteria(typeof

(RobotTracking));
                creieria.Add(Expression.Sql("LUNGUID >= '" + lunguid+"'"));
                creieria.Add(Expression.Sql(" ACT<>'" + act+"'"));
                list = creieria.List<RobotTracking>();
                foreach (RobotTracking tracking in list)
                {
                    Console.WriteLine(tracking.ToString());
                } 
 }  

 }
}
说明:上面的代码说明了Composite主键的一般用法,同时演示了插入,删除,以及两种不同方

式的查询操作。
补充一点,在插入TOC字段是,虽然数据库的默认值是Sysdate,如果没有robotTracking.TCo=
DateTime.Now这句,那么插入到数据中的值并不是我们期望的Sysdate。想知道具体是什么值的

话可以实际的试试。

 

转载于:https://www.cnblogs.com/chenzhuo131/p/8979140.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值