NHibernate 映射基礎(第三篇) 簡單映射、聯合主鍵


  NHibernate完全靠配置文件獲取其所需的一切信息,其中映射文件,是其獲取數據庫與C#程序關系的所有信息來源。

一、簡單映射

  下面先來一個簡單的例子,然后隨着不斷地對這個例子修修改改,從而真正了解映射文件。具體的資料可以查看http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html

  先來看一張表:

  

  映射文件Product.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Model.ProductModel, Model" table="Product">
    <id name="ProductId" column="ProductId" type="Int32">
      <generator  class="native"/>
    </id>
    <property name="ProductName" column="ProductName" type="String"/>
    <property name="ProductPrice" column="ProductPrice" type="float"/>
    <property name="ProductDiscount" column="ProductDiscount" type="float"/>
    <!--這個屬性沒有與之對應的列,其列為ProductPrice * ProductDiscount相乘得來-->
    <property name="ActualPrice" formula="ProductPrice * ProductDiscount" type="float"/>
  </class>
</hibernate-mapping>

  PersonModel.cs:

namespace Model
{
    public class ProductModel
    {
        public virtual int ProductId { get; set; }
        public virtual string ProductName { get; set; }
        public virtual float ProductPrice { get; set; }
        public virtual float ProductDiscount { get; set; }
        public virtual float ActualPrice { get; set; }  //數據庫里並沒有這個字段
    }
}

  在這里要注意下最后一個字段,數據庫里並沒有這個字段。

  ProductDao.cs:

    public class ProductDao
    {
        public ProductModel GetProduct(int Id)
        {
            ISession NSession = NHibernateHelper.GetSession();
            return NSession.Get<ProductModel>(Id);
        }
    }

  Program.cs:

        static void Main(string[] args)
        {
            ProductDao dao = new ProductDao();
            ProductModel pm = dao.GetProduct(1);
            Console.WriteLine(pm.ProductId + " " + pm.ProductName + " " + pm.ProductPrice + " " + pm.ProductDiscount + " " + pm.ActualPrice);
        }

  顯示結果如下:

  

  你可能奇怪,為什么最后一個字段數據庫沒有,但是為什么也能夠查詢出結果呢?答案在於配置里面的

  formula="ProductPrice * ProductDiscount"

  這個屬性配置之后,允許某字段的值從其他字段計算獲得。

  我們來看看生成的SQL代碼

exec sp_executesql N'SELECT productmod0_.ProductId as ProductId4_0_, productmod0_.ProductName as ProductN2_4_0_, productmod0_.ProductPrice as ProductP3_4_0_, 
productmod0_.ProductDiscount as ProductD4_4_0_, productmod0_.ProductPrice * productmod0_.ProductDiscount as formula0_0_ FROM Product productmod0_ WHERE productmod0_.ProductId=@p0',N'@p0 
int',@p0=1
--以上SQL代碼相當於
SELECT ProductId,ProductName,ProductPrice,ProductDiscount, ProductPrice * ProductDiscount AS formula FROM Product

  其實,這是NHibernate根據我們的配置,幫我們生成了SQL語句,計算出另外的字段並綁定的對應的屬性當中。

  下面我們開始來不斷更改,以了解更多的NHibernate配置的作用。

  我們將Product.hbm.xml的第一行加上下面這一句:

  select-before-update="true"
 <class name="Model.ProductModel, Model" table="Product" select-before-update="true">

  然后PersonDao.cs增加此方法:

        public void UpdateProduct(ProductModel product)
        {
            ISession NSession = NHibernateHelper.GetSession();
            NSession.Update(product);
            NSession.Flush();
        }

  用於更新一個Product。

  Program.cs:

        static void Main(string[] args)
        {
            ProductDao dao = new ProductDao();
            ProductModel pm = dao.GetProduct(1);
            dao.UpdateProduct(pm);
        }

  對於此操作,SQL Server Profiler檢測到執行了如下語句:

exec sp_executesql N'SELECT productmod0_.ProductId as ProductId4_0_, productmod0_.ProductName as ProductN2_4_0_, productmod0_.ProductPrice as ProductP3_4_0_, 
productmod0_.ProductDiscount as ProductD4_4_0_, productmod0_.ProductPrice * productmod0_.ProductDiscount as formula0_0_ FROM Product productmod0_ WHERE productmod0_.ProductId=@p0',N'@p0 
int',@p0=1
--相當於如下語句
SELECT ProductId,ProductName,ProductPrice,ProductDiscount FROM Product WHERE ProductId = 1

  而當我們去掉

  select-before-update  
  或者將其值設置為flase時,就會直接執行UPDATE語句。select-before-update的作用在於,控制在UPDATE語句之前是否先執行一次查詢,以檢查對象是否有變化,當數據發生變化之后才UPDATE,否則不UPDATE。

二、聯合主鍵

  新建一張表如下:

     

   以上3列數據都是NVarchar()類型。

  下面來看配置映射文件:

  Composite.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Model.CompositeModel, Model" table="Composite">
    <composite-id name="Pk" class="Model.PKModel, Model">  //name為主實體類的屬性名
        <key-property name="Id1" type="String" column="Id1"/>
        <key-property name="Id2" type="String" column="Id2"/>
    </composite-id>
    <property name="Name" column="Name" type="String"/>
  </class>
</hibernate-mapping>

  CompositeModel.cs

    public class CompositeModel
    {
        public virtual PKModel Pk { get; set; }
        public virtual string Name { get; set; }
    }

  PKModel.cs

    public class PKModel
    {
        public virtual string Id1 { get; set; }
        public virtual string Id2 { get; set; }

        /// <summary>
        /// 判斷兩個對象是否相同,這個方法需要重寫
        /// </summary>
        /// <param name="obj">進行比較的對象</param>
        /// <returns>真true或假false</returns>
        public override bool Equals(object obj)
        {
            if (obj is PKModel)
            {
                PKModel pk = obj as PKModel;
                if (this.Id1 == pk.Id1 && this.Id2 == pk.Id2)
                {
                    return true;
                }
            }
            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

   操作:

   class Program
    {
        static void Main(string[] args)
        {
            ISessionFactory _sessionFactory = new Configuration().Configure().BuildSessionFactory();
            using(ISession NSession = _sessionFactory.OpenSession())
            {
                IList<CompositeModel> ListComposite = NSession.Query<CompositeModel>().ToList();
                foreach (var c in ListComposite)
                {
                    Console.WriteLine(c.Name);
                }

                //查詢單條
                PKModel pk = new PKModel();
                pk.Id1 = "01";
                pk.Id2 = "1";
                CompositeModel m = NSession.Get<CompositeModel>(pk);
                Console.WriteLine(m.Name);
            }
            Console.ReadKey();
        }
    }

  輸出:

   

   要點:1、聯合主鍵提取出來作為一個類

      2、要重寫兩個方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM