第一个NHibernate应用程序(一)
1.搭建基本框架
1)创建一个空的MVC项目Shop.Web
2)创建类库Shop.Data(数据)
3)创建类库Shop.Domain(映射模型model)
4)创建类库Shop.Business(业务逻辑)
5)创建数据库Shop,创建表Cart(字段Id,Name)
2.安装NHibernate
我们需要连接获取到数据(使用NHibernate),所以我们在Shop.Data中右击引用=》点击Nuget程序包,查询NHibernate,安装(安装完毕后,引用会多出一些东西,你可以对比一下其它类库的引用)
3.数据库连接配置(Shop.Data中进行)
1)寻找项目中的MSSQL.cfg.xml(你可以右键项目在 项目 \Shop.Web\packages\NHibernate.5.2.4\ConfigurationTemplates文件里头找到,不同的xml支持不同的数据库--里头我们可以看到其他数据库的链接)
2)我们将MSSQL.cfg.xml复制加载到Shop.Web项目里头,并改名为hibernate.cfg.xml,当做数据库连接的配置,修改里头hibernate.cfg.xml的内容(右击hibernate.cfg.xml文件属性的“高级”修改成:“如果较新则复制”)
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?> <!-- This template was written to work with NHibernate.Test. Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it for your own use before compile tests in VisualStudio. --> <!-- This is the System.Data.dll provider for SQL Server --> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" > <session-factory name="NHibernate.Test"> <!--定制IDriver的类型.--> <property name="connection.driver_class">NHibernate.Driver.Sql2008ClientDriver</property> <!--连接字符串--> <property name="connection.connection_string"> Server=.;database=Shop;uid=sa;pwd=sa </property> <!--NHibernate方言(Dialect)的类名 - 可以让 NHibernate 使用某些特定的数据库平台的特性--> <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property> <!--指定映射文档中所在程序集--> <mapping assembly="Shop.Domain"/> </session-factory> </hibernate-configuration>
4.Web页面
1)由于前面我们的Shop.Web是一个空项目,添加个Controllers文件夹后,右键添加个控制器HomeControllers(程序会自动加载其它配置文件)
5.我们返回到Shop.Data那边,准备给它弄个NHibernateHelper.cs(单例加载数据,用于创建ISessionFactory,和配置ISessionFactory,并且打开一个新的ISession方法)
说明:一个ISession代表一个单线程的单元操作。
ISessionFactory是线程安全的,很多线程可以同时访问它。
ISession不是线程安全的,代表与数据库之间的一次操作。
ISession通过ISessionFactory打开,在所有的工作完成之后需要将其关闭。
SessionFactory的创建很占用系统资源,一般整个应用程序中只创建一次。因此这里通过 _sessionFactory == null 来实现一个最简单的单例模式。
using NHibernate; using NHibernate.Cfg; namespace Shop.Data { public class NHibernateHelper { private static ISessionFactory _sessionFactory; /// <summary> /// 创建ISessionFactory /// </summary> public static ISessionFactory SessionFactory { get { //配置ISessionFactory return _sessionFactory == null ? (new Configuration()).Configure().BuildSessionFactory():_sessionFactory; } } } }
6.持久化类,创建映射模型Cart.cs(在Shop.Domain中创建一个Entities文件夹,在Entities中添加类Cart)
namespace Shop.Domain.Entities { public class Cart { public virtual int Id { get; set; } public virtual string Name { get; set; } } }
注:NHibernate默认使用代理功能,要求持久化类不是sealed,并且其公共方法、属性和事件声明为virtual。
7.编写持久化映射文件
1)在Shop.Domain中创建映射文件Cart.hbm.xml
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Shop.Domain" namespace="Shop.Domain.Entities"> <!--类的全称,程序集,数据库表名称--> <class name="Shop.Domain.Entities.Cart,Shop.Domain" table="Cart"> <id name="Id" column="Id" type="int" /> <property name="Name" column="Name" type="string" /> </class> </hibernate-mapping>
2)修改Cart.hbm.xml属性配置(“生成操作”:“嵌入的资源”)
8.添加数据访问层类CartData.cs(在Shop.Data中添加,并且引用项目Shop.Domain)
说明:使用using子句,在using代码块完成后,自动调用ISession的Dispose方法关闭Session。
using NHibernate; using Shop.Domain.Entities; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace Shop.Data { public class CartData { /// <summary> /// 根据条件得到数据集合 /// </summary> /// <param name="where"></param> /// <returns></returns> public IList<Cart> GetCartList(Expression<Func<Cart,bool>> where) { try { using (ISession session = NHibernateHelper.SessionFactory.OpenSession()) { return session.Query<Cart>().Select(x=>new Cart { Id = x.Id, Name = x.Name }).Where(where).ToList(); } } catch (Exception ex) { throw ex; } } } }
9.添加业务逻辑CartBusiness.cs(在Shop.Business中添加,并且引用项目Shop.Domain和Shop.Data)
using Shop.Data; using Shop.Domain.Entities; using System; using System.Collections.Generic; using System.Linq.Expressions; namespace Shop.Business { public class CartBusiness { private CartData _cartData; public CartBusiness() { _cartData = new CartData(); } /// <summary> /// 根据条件得到数据集合 /// </summary> /// <param name="where"></param> /// <returns></returns> public IList<Cart> GetCartList(Expression<Func<Cart, bool>> where) { return _cartData.GetCartList(where); } } }
10.添加视图和控制器(我们在前面创建的HomeCotrollers,引用项目Shop.Domain和Shop.Business)
1)在HomeController.cs添加代码
using Shop.Business; using System.Web.Mvc; namespace Shop.Web.Controllers { public class HomeController : Controller { CartBusiness _cartBusiness = new CartBusiness(); // GET: Home public ActionResult Index() { var result = _cartBusiness.GetCartList(c=>1 == 1); return View(result); } } }
2)右键控制器Index添加视图
全部重新生成后,选择Shop.Web为启动项,运行出现 Antlr3.Runtime 版本不对
经查询: Shop.Web 的引用 存在 Antlr3.Runtime,并且版本和Shop.Data的不一致。(Antlr3.Runtime是安装NHibernate包里头的一个dll)
解决:Shop.Web项目Nuget安装 NHibernate
重新生成运行:
参阅:ASP.NET MVC 企业级实战(邹琼俊)