一,摘要
在本篇文章中我们覆盖如何安装配置Nhibernate,以及在MVC中如何使用它.
二,什么是Nhibernate
Nhibernate是一个应用于.NET中的对象-关系映射器,它将对象模型映射到关系型数据库,在本文中你将看到Nhibernate处理大部分持久层相关联的任务,从http://sourceforge.net/projects/nhibernate/files/站点下载Nhibernate
三,安装Nhibernate
下载压缩包,并且解压到你的电脑上,这样就安装好了.
四,创建ASP.NET MVC项目
创建一个新的MVC项目,伴随着单元测试项目.添加两个类库:Infrastructure与Core.这是一个非常简单的模型帮助我们理解Nhibernate是如何工作的:一个博客帖子属于一个或者多个类别,一个类别可能拥有一个或者多个帖子 我们将使用SQL Server2008速成版创建我们的数据库,当然也可以在Visual Studio里创建模型,然后通过编写Nhibernate配置去创建数据库.
五,创建模型
下一步去创建我们的模型,它是我们的数据库面向对象的表现,我们将使用Visual Studio的类设计器创建它
六,Repositories
repository允许我们去创建,查询,更新,删除我们的对象.repository独立于数据库.我们将创建2个repository:PostRepository与CategoryRepository,两个repositorys将实现如下接口: IRepository.cs
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using System; 6: using System.Collections.Generic; 7: using System.Linq; 8: using System.Text; 9: 10: namespace Core 11: { 12: public interface IRepository 13: { 14: void Save(T entity); 15: void Update(T entity); 16: void Delete(Guid id); 17: T GetById(Guid id); 18: T GetAll(); 19: } 20: }去创建repositorys,我们首先需要创建一个辅助类NHibernate session NHibernateHelper.cs
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using NHibernate.Cfg; 6: using NHibernate; 7: 8: namespace Core.Domain.Repositories 9: { 10: public class NHibernateHelper 11: { 12: private static ISessionFactory _sessionFactory; 13: 14: private static ISessionFactory SessionFactory 15: { 16: get 17: { 18: if (_sessionFactory == null) 19: { 20: var configuration = new Configuration(); 21: configuration.Configure(); 22: _sessionFactory = configuration.BuildSessionFactory(); 23: } 24: return _sessionFactory; 25: } 26: } 27: 28: public static ISession OpenSession() 29: { 30: return SessionFactory.OpenSession(); 31: } 32: } 33: }下一步我们创建repositorys PostRepository.cs
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using Core.Domain.Model; 6: using NHibernate; 7: using NHibernate.Criterion; 8: 9: namespace Core.Domain.Repositories 10: { 11: public class PostRepository: IRepository 12: { 13: #region IRepository Members 14: 15: void IRepository .Save(Post entity) 16: { 17: using (ISession session = NHibernateHelper.OpenSession()) 18: { 19: using (ITransaction transaction = session.BeginTransaction()) 20: { 21: session.Save(entity); 22: transaction.Commit(); 23: } 24: } 25: } 26: 27: void IRepository .Update(Post entity) 28: { 29: using (ISession session = NHibernateHelper.OpenSession()) 30: { 31: using (ITransaction transaction = session.BeginTransaction()) 32: { 33: session.Update(entity); 34: transaction.Commit(); 35: } 36: } 37: } 38: 39: void IRepository .Delete(Guid id) 40: { 41: using (ISession session = NHibernateHelper.OpenSession()) 42: { 43: using (ITransaction transaction = session.BeginTransaction()) 44: { 45: session.Delete(id); 46: transaction.Commit(); 47: } 48: } 49: } 50: 51: Post IRepository .GetById(Guid id) 52: { 53: using (ISession session = NHibernateHelper.OpenSession()) 54: return session.CreateCriteria ().Add(Restrictions.Eq( "Id", id)).UniqueResult (); 55: } 56: 57: Post IRepository .GetAll() 58: { 59: throw new NotImplementedException(); 60: } 61: 62: #endregion 63: } 64: }CategoryRepository.cs
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using Core.Domain.Model; 6: using NHibernate; 7: using NHibernate.Criterion; 8: 9: namespace Core.Domain.Repositories 10: { 11: public class CategoryRepository: IRepository 12: { 13: #region IRepository Members 14: 15: void IRepository .Save(Category entity) 16: { 17: using (ISession session = NHibernateHelper.OpenSession()) 18: { 19: using (ITransaction transaction = session.BeginTransaction()) 20: { 21: session.Save(entity); 22: transaction.Commit(); 23: } 24: } 25: } 26: 27: void IRepository .Update(Category entity) 28: { 29: using (ISession session = NHibernateHelper.OpenSession()) 30: { 31: using (ITransaction transaction = session.BeginTransaction()) 32: { 33: session.Update(entity); 34: transaction.Commit(); 35: } 36: } 37: } 38: 39: void IRepository .Delete(Guid id) 40: { 41: using (ISession session = NHibernateHelper.OpenSession()) 42: { 43: using (ITransaction transaction = session.BeginTransaction()) 44: { 45: session.Delete(id); 46: transaction.Commit(); 47: } 48: } 49: } 50: 51: Category IRepository .GetById(Guid id) 52: { 53: using (ISession session = NHibernateHelper.OpenSession()) 54: return session.CreateCriteria ().Add(Restrictions.Eq( "Id", id)).UniqueResult (); 55: } 56: 57: Category IRepository .GetAll() 58: { 59: throw new NotImplementedException(); 60: } 61: 62: #endregion 63: } 64: }我们看到在Repository中首先创建Session然后调用Nhibernate中的方法
七,回顾
到目前为止,我们做了如下事情: 1.创建Core类库,引用Nhibernate程序集 2.在Core类库里我们创建了两个模型类:"Post.cs”,"Category.cs”,post类有一个指向category类的集合 3.创建了两个Repository去查询,更新,删除,编辑我们的模型
八,映射
现在在我们的Infrastructure类库中创建模型层到数据库的映射,我们需要在Nhibernate中配置XML文件,命名遵循[ClassName].hbm.xml的规范 我们将创建两个新文件:Category.hbm.xml 与Post.hbm.xml,每一个类映射到数据库中的一张表,属性映射到表中的列,当然你也能制定数据类型,首先我们创建Category.hbm.xml文件:
1: xml version="1.0" encoding="utf-8" ?> 2: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 3: namespace="Core.Domain.Model" 4: assembly="Core"> 5: 6: <class name="Category" table="Categories" dynamic-update="true"> 7: <cache usage="read-write"/> 8: <id name="Id" column="Id" type="Guid"> 9: <generator class="guid"/> 10: id> 11: <property name="Name" length="100"/> 12: class> 13: hibernate-mapping>注意:一定要设置每个映射文件的简历动作为"Embedded Resource",这样Nhibernate就能在程序集中找到正确的文件
九,配置Nhibernate
下一步我们在hibernate.cfg.xml文件中设置Nhibernate的连接以及参数,在动态代理系统中,Nhibernate有一个"Lazy-Loading"特性,我们需要添加如下程序集去支持它: 1.Castle.Core 2.Castle.DynamicProxy2 3.NHibernate.ByteCode.Castle.dll 然后创建如下配置文件: hibernate.cfg.xml
1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 2: <session-factory> 3: <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver property> 4: <property name="connection.connection_string">server=./SQLExpress;database=NHibernate101;Integrated Security=true; property> 5: <property name="show_sql">true property> 6: <property name="dialect">NHibernate.Dialect.MsSql2008Dialect property> 7: <property name="cache.use_query_cache">false property> 8: <property name="adonet.batch_size">100 property> 9: <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle property> 10: <mapping assembly="Infrastructure" /> 11: session-factory> 12: hibernate-configuration>十,测试
现在我们去测试我们的Nhibernate配置,通过测试我们添加一些数据到我们的"Categories"表,那么首先要引用Nbibernate程序集以及拷贝hibernate.cfg.xml到我们的测试项目下,添加如下引用: 1.Castle.Core 2.Castle.DynamicProxy2 3.Infrastructure 4.NHibernate 5.NHibernate.ByteCode.Castle 添加如下测试方法:
1: [TestMethod] 2: [DeploymentItem("hibernate.cfg.xml")] 3: public void CanCreateCategory() 4: { 5: IRepository repo = new CategoryRepository(); 6: Category category = new Category(); 7: category.Name = "ASP.NET"; 8: 9: repo.Save(category); 10: 11: } 运行我们的测试方法,我们将看到测试方法成功通过: 核查我们的数据库,查看category是否已经添加:随下的文章中我们将继续探索!