关注开源代码的实际应用
NHibernate中使用 ISession.Load 加载的只是未经初始化的 Proxy,而 ISession.Get 加载的对象是初始化的。
所以,如果取完数据就关闭Session需要使用ISession.Get以避免使用Lazy-load的对象属性为null。
用过NHibernte的人都知道需要在每个实体类的public属性前加上virtual关键字,才可以使用NHibernate的延迟加载(Lazy-loading)的功能。大多数情况下,没有谁对这种开发方式有意见,但是在我看来这是一种丑陋的开发方式,并且有时会漏写virtual关键字需要在程序进行时才能通过抛出的异常知道问题所在。这里通过AOP框架Postsharp解决此问题。
1、Postsharp程序集或代码可从http://www.postsharp.org/网站下载。下载“Unsealer”并将“Unsealer.Weaver.dll”与“Unsealer.psplugin”相关文件复制到Postsharp安装目录下Plugins文件夹下。在NHibernate实体类所在项目中引用PostSharp.Public.dll和Unsealer.dll。
2、两种方式任选一种:①在每个实体类前加上[Unseal]特性;②在AssemblyInfo.cs文件中加上[assembly: Unseal(AttributeTargetTypes = "*")]。
这样就无需再为NHibernate实体类属性加上virtual了。
注:通过此种方式定义实体类时,任何实体类不可定义为sealed类型。
1、先数据库设计,再实体类设计
如果历史遗留的系统数据库已经存在,或者个人开发习惯于先设计数据库,这两种情况下可通过CodeSmith或者MyGeneration结合NHibernte相关代码生成模板由数据库表结构生成实体类与HBM文件。
2、先实体类再数据库
对 于全新的系统开发,由于没有历史遗留数据库影响,可以通过这种方式进行开发,更加适合进行OOD。使用这种方式开发也有两种选择:1、分别编写实体类与 HBM映射配置文件。2、通过NHibernate.Mapping.Attribute将映射关系以Attribute的形式标注于实体类上。最后再通 过实体类与映射信息生成数据库Schema。
我更喜欢以最后一种方式进行开发。
NHibernate通过Session工厂取得Connection并结合Command执行存储过程:
1、通过ICriteria结合Expression.Sql进行查询
- ICriteria cri = this.Session.DbSession.CreateCriteria(typeof(Mag.Article.LightNews));
- cri.Add(Expression.Sql(string.Format("contains(title,'{0}')", key)));
2、使用ISQLQuery直接通过SQL语句进行查询
- string sql = string.Format("select id from [user] where contains(loginname,'{0}')", pKey);
- ISQLQuery query = this.Session.DbSession.CreateSQLQuery(sql);
- query.AddScalar("id",NHibernateUtil.Int32);
- System.Collections.ArrayList ids = new System.Collections.ArrayList();
- query.List(ids);//或者使用query.List<Entity.TypeName>,但sql语句不能指定字段