NHibernate 映射基础(第三篇) 简单映射、联合主键

  NHibernate完全靠配置文件获取其所需的一切信息,其中映射文件,是其获取数据库与C#程序关系的所有信息来源。

一、简单映射

  下面先来一个简单的例子,然后随着不断地对这个例子修修改改,从而真正了解映射文件。具体的资料可以查看http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html

  先来看一张表:

  NHibernate 映射基础(第三篇) 简单映射、联合主键

  映射文件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。

二、联合主键

  新建一张表如下:

  NHibernate 映射基础(第三篇) 简单映射、联合主键   

   以上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();

        }

    }

  输出:

   NHibernate 映射基础(第三篇) 简单映射、联合主键

   要点:1、联合主键提取出来作为一个类

      2、要重写两个方法

你可能感兴趣的:(Hibernate)