NHibernate从入门到精通系列(5)——持久对象的生命周期(下)

长平狐 发布于 2012/06/11 11:54
阅读 186
收藏 1

 

内容摘要

持久化类

持久化生命周期中的回调

合法性验证回调

 

一、持久化类(Persistent Classes)

1.1 什么是持久化类

回答这个问题之前先回答什么是持久化。所谓的持久化就是把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。然而持久化类就是持久化数据的载体,在应用程序中,用来实现业务问题实体的(如,在电子商务应用程序中的Customer和Order) 类就是持久化类。不能认为所有的持久化类的实例都是持久的状态——一个实例的状态也可能 是瞬时的或脱管的。 如果这些持久化类遵循一些简单的规则,NHibernate能够工作得更好,这些规则也被称作 简单传统CLR对象(POCO:Plain Old CLR Object)编程模型。

之前用到的“Product”类,就是持久化类

 

Product
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  Domain
{
    
///   <summary>
    
///  商品
    
///   </summary>
     public   class  Product
    {
        
///   <summary>
        
///  ID
        
///   </summary>
         public   virtual  Guid ID {  get set ; }

        
///   <summary>
        
///  编号
        
///   </summary>
         public   virtual   string  Code {  get set ; }

        
///   <summary>
        
///  名称
        
///   </summary>
         public   virtual   string  Name {  get set ; }

        
///   <summary>
        
///  规格
        
///   </summary>
         public   virtual   string  QuantityPerUnit {  get set ; }

        
///   <summary>
        
///  单位
        
///   </summary>
         public   virtual   string  Unit {  get set ; }

        
///   <summary>
        
///  售价
        
///   </summary>
         public   virtual   decimal  SellPrice {  get set ; }

        
///   <summary>
        
///  进价
        
///   </summary>
         public   virtual   decimal  BuyPrice {  get set ; }

        
///   <summary>
        
///  备注
        
///   </summary>
         public   virtual   string  Remark {  get set ; }
    }
}

 

 

然而持久化类须满足一定的规则。

 

1.2持久化类的规则

  • 实现一个默认的(即无参数的)构造方法(constructor)
  • 提供一个标识属性(identifier property)(可选)
  • 使用非密封(non-sealed)类以及虚方法(virtual methods) (可选)

 

二、持久化生命周期中的回调

2.1 ILifecycle接口介绍

持久化类可以实现ILifecycle接口,它可以提供一些用于回调的方法, 可以让持久化对象在Save或Load之后,或者在Delete或Update之前进行必要的初始化与清除步骤。

让我们看一下ILifecycle接口

 

ILifecycle
     public   interface  ILifecycle
    {
        LifecycleVeto OnDelete(ISession s);
        
void  OnLoad(ISession s,  object  id);
        LifecycleVeto OnSave(ISession s);
        LifecycleVeto OnUpdate(ISession s);
    }

 

 

其中ILifecycle接口的方法如下:

(1)

OnSave - 在对象即将被save或者insert的时候回调

(2)

OnUpdate - 在对象即将被update的时候回调(也就是对象被传递给ISession.Update()的时候)

(3)

OnDelete - 在对象即将被delete(删除)的时候回调

(4)

OnLoad - 在对象刚刚被load(装载)后的时候回调

 

如果OnSave(), OnUpdate() 或者 OnDelete()返回LifecycleVeto.Veto,那么操作就被悄悄地取消了。 如果其中抛出了CallbackException异常,操作被取消,这个异常会被继续传递给应用程序。

 

2.2 ILifecycle的demo

实体:

Product
///   <summary>
    
///  商品
    
///   </summary>
     public   class  Product : ILifecycle
    {
        
///   <summary>
        
///  ID
        
///   </summary>
         public   virtual  Guid ID {  get set ; }

        
///   <summary>
        
///  编号
        
///   </summary>
         public   virtual   string  Code {  get set ; }

        
///   <summary>
        
///  名称
        
///   </summary>
         public   virtual   string  Name {  get set ; }

        
///   <summary>
        
///  规格
        
///   </summary>
         public   virtual   string  QuantityPerUnit {  get set ; }

        
///   <summary>
        
///  单位
        
///   </summary>
         public   virtual   string  Unit {  get set ; }

        
///   <summary>
        
///  售价
        
///   </summary>
         public   virtual   decimal  SellPrice {  get set ; }

        
///   <summary>
        
///  进价
        
///   </summary>
         public   virtual   decimal  BuyPrice {  get set ; }

        
///   <summary>
        
///  备注
        
///   </summary>
         public   virtual   string  Remark {  get set ; }


        
public   virtual  LifecycleVeto OnDelete(NHibernate.ISession s)
        {
            Console.WriteLine(
" 您调用了Delete()方法! " );
            
return  LifecycleVeto.NoVeto;
        }

        
public   virtual   void  OnLoad(NHibernate.ISession s,  object  id)
        {
            Console.WriteLine(
" 您调用了Load()方法! " );
        }

        
public   virtual  LifecycleVeto OnSave(NHibernate.ISession s)
        {
            Console.WriteLine(
" 您调用了Save()方法! " );
            
return  LifecycleVeto.NoVeto;
        }

        
public   virtual  LifecycleVeto OnUpdate(NHibernate.ISession s)
        {
            Console.WriteLine(
" 您调用了Update()方法! " );
            
return  LifecycleVeto.NoVeto;
        }
    }

 

 

单元测试:

 

LifecycleTest
[TestFixture]
    
public   class  LifecycleTest
    {
        
private  ISessionFactory sessionFactory;

        
private   static   readonly  Guid s_id  =  Guid.NewGuid();

        [SetUp]
        
public   void  Init()
        {
            var cfg 
=   new  NHibernate.Cfg.Configuration().Configure( " Config/hibernate.cfg.xml " );
            sessionFactory 
=  cfg.BuildSessionFactory();
        }

        [Test]
        
public   void  SaveTest()
        {
            
using  (ISession session  =   this .sessionFactory.OpenSession())
            {
                
using  (ITransaction tran  =  session.BeginTransaction())
                {
                    
try
                    {
                        var product 
=   new  Product
                        {
                            ID 
=  s_id,
                            BuyPrice 
=  10M,
                            Code 
=   " ABC123 " ,
                            Name 
=   " 电脑 " ,
                            QuantityPerUnit 
=   " 20x1 " ,
                            SellPrice 
=  11M,
                            Unit 
=   " "
                        };

                        session.Save(product);

                        tran.Commit();
                    }
                    
catch  (Exception ex)
                    {
                        tran.Rollback();
                        
throw  ex;
                    }
                }
            }
        }

        [Test]
        
public   void  UpdateTest()
        {
            
using  (ISession session  =   this .sessionFactory.OpenSession())
            {
                
using  (ITransaction tran  =  session.BeginTransaction())
                {
                    
try
                    {
                        var product 
=  session.Load < Product > (s_id);

                        product.BuyPrice 
=  12M;
                        session.Update(product);

                        tran.Commit();
                    }
                    
catch  (Exception ex)
                    {
                        tran.Rollback();
                        
throw  ex;
                    }
                }
            }
        }

        [Test]
        
public   void  DeleteTest()
        {
            
using  (ISession session  =   this .sessionFactory.OpenSession())
            {
                
using  (ITransaction tran  =  session.BeginTransaction())
                {
                    
try
                    {
                        var product 
=  session.Load < Product > (s_id);

                        session.Delete(product);

                        tran.Commit();
                    }
                    
catch  (Exception ex)
                    {
                        tran.Rollback();
                        
throw  ex;
                    }
                }
            }
        }
    }

 

 

运行SaveTest()方法的效果,如图2.2.1所示。

图2.2.1

 

运行UpdateTest()方法的效果,如图2.2.2所示。奇怪的是OnUpdate()回调没有工作,这是因为在NHibernate 1.x 以后的版本,ILifecycle接口已经不建议使用了。

图2.2.2

 

运行DeleteTest()方法的效果,如图2.2.3所示。

图2.2.3

 

三、合法性验证回调

合法性验证(IValidatable)回调是在持久化类在保存其持久化状态前进行合法性检查的接口。

public   interface  IValidatable
{
        
void  Validate();
}

 

 

如果发现对象违反了某条规则,应该抛出一个 ValidationFailure异常。在 Validatable实例的 Validate()方法内部不应该改变它的状态。

ILifecycle接口的回调方法不同,Validate()可能在任何时间被调用。应用程序不应该把Validate()调用和商业功能联系起来。

 

实现代码如下:

 

代码
public   class  Product : IValidatable
    {

        ....


        
///   <summary>
        
///  进价
        
///   </summary>
         public   virtual   decimal  BuyPrice {  get set ; }


        
public   virtual   void  Validate()
        {
            
if  ( this .BuyPrice  >=  12M)
            {
                
throw   new  ValidationFailure( " 进货价格太高,无法受理! " );
            }
        }
    }

 

 

运行效果如图3.1所示

图3.1

 

总结:目前NHibernate 3.0版本中不建议使用ILifecycle和IValidatable接口。因为这样NHibernate框架就会对持久化类产生侵入性。

 

代码下载

出处:http://www.cnblogs.com/GoodHelper/archive/2011/02/18/nhibernate05.html

欢迎转载,但需保留版权。

 


原文链接:http://www.cnblogs.com/GoodHelper/archive/2011/02/18/nhibernate05.html
加载中
返回顶部
顶部