NH用了很长时间一直都是用2.X版本,今天体验了一下3.3。记录一下两者使用上的一些区别。
一、代理
//2.x 写法 <property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property> //3.X写法 <property name='proxyfactory.factory_class'>NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate</property>
因为3.X已经内部集成proxy generator,因此无需另外的NHibernate.ByteCode.LinFu.dll or NHibernate.ByteCode.Castle.dll了。
二、延迟加载
public class Child public class Parent { Public virtual Child Child{get;set;} }
Parent p=XXXXXXX; If (p.Child is Child) { //do something }
由于有代理的延迟加载,p.Child并不是Child类型。此处的is判断是false。
NH3.X的Parent Map文件中<many-to-one name="Child" lazy="no-proxy"/>将会有两个效果
- Child属性依然是延迟加载(NH2.X若声明是no proxy会立即加载)
- 首次访问Child属性时,NH会从数据库加载数据,并且返回实际类型。
三、Hql写法的变更
2.X删除数据的写法
ISession session= GetSession(); string hql = "from table1 tab where DataTime between :a and :b"; IType[] itypes = new IType[] { NHibernateUtil.DateTime, NHibernateUtil.DateTime }; session().Delete(hql, new object[] { startDate, endDate }, itypes);
以上的写法在3.X中会产生异常: KeyNotFoundException: 给定关键字不在字典中。
3.X写法1:放弃参数命名,全部用?代替,阅读性不是太好。
ISession session= GetSession(); string hql = "from table1 tab where DataTime between ? and ?"; IType[] itypes = new IType[] { NHibernateUtil.DateTime, NHibernateUtil.DateTime }; session().Delete(hql, new object[] { startDate, endDate }, itypes);
3.X写法2:该方法与上一种差不多,但在hql中声明了是delete操作。
string hql = "delete from table1 tab where DataTime between ? and ?"; IType[] itypes = new IType[] { NHibernateUtil.DateTime, NHibernateUtil.DateTime }; IQuery q = session.CreateQuery(hql); for (int i = 0; i < vals.Length; i++) { q.SetParameter(i, vals[i], itypes[i]); } q.ExecuteUpdate();
3.X写法3:每个hql参数用SetXXType显式赋值。
string hql = "delete from table1 tab where DataTime between :start and :end"; IType[] itypes = new IType[] { NHibernateUtil.DateTime, NHibernateUtil.DateTime }; IQuery q = session.CreateQuery(hql); q.SetDateTime(“start”,a); q.SetDateTime(“end”, b); q.ExecuteUpdate();
虽然SetParameter重载了多个方法,但position只能用于“?”声明的hql,name只能用于命名参数的hql。否则会产生异常。
IQuery SetParameter(int position, object val, IType type); IQuery SetParameter(string name, object val, IType type);