NHibernate學習之一:CompositeKey的實現

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。想知道具體是什麼值的

話可以實際的試試。

發佈了6 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章