一,摘要
在本篇文章中我们覆盖如何安装配置Nhibernate,以及在MVC中如何使用它.
二,什么是Nhibernate
Nhibernate是一个应用于.NET中的对象-关系映射器,它将对象模型映射到关系型数据库,在本文中你将看到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;
<!--CRLF-->
2: using System.Collections.Generic;
<!--CRLF-->
3: using System.Linq;
<!--CRLF-->
4: using System.Text;
<!--CRLF-->
5: using System;
<!--CRLF-->
6: using System.Collections.Generic;
<!--CRLF-->
7: using System.Linq;
<!--CRLF-->
8: using System.Text;
<!--CRLF-->
9:
<!--CRLF-->
10: namespace Core
<!--CRLF-->
11: {
<!--CRLF-->
12: public interface IRepository<t></t>
<!--CRLF-->
13: {
<!--CRLF-->
14: void Save(T entity);
<!--CRLF-->
15: void Update(T entity);
<!--CRLF-->
16: void Delete(Guid id);
<!--CRLF-->
17: T GetById(Guid id);
<!--CRLF-->
18: T GetAll();
<!--CRLF-->
19: }
<!--CRLF-->
20: }
<!--CRLF-->
去创建repositorys,我们首先需要创建一个辅助类NHibernate session
NHibernateHelper.cs
1: using System;
<!--CRLF-->
2: using System.Collections.Generic;
<!--CRLF-->
3: using System.Linq;
<!--CRLF-->
4: using System.Text;
<!--CRLF-->
5: using NHibernate.Cfg;
<!--CRLF-->
6: using NHibernate;
<!--CRLF-->
7:
<!--CRLF-->
8: namespace Core.Domain.Repositories
<!--CRLF-->
9: {
<!--CRLF-->
10: public class NHibernateHelper
<!--CRLF-->
11: {
<!--CRLF-->
12: private static ISessionFactory _sessionFactory;
<!--CRLF-->
13:
<!--CRLF-->
14: private static ISessionFactory SessionFactory
<!--CRLF-->
15: {
<!--CRLF-->
16: get
<!--CRLF-->
17: {
<!--CRLF-->
18: if (_sessionFactory == null)
<!--CRLF-->
19: {
<!--CRLF-->
20: var configuration = new Configuration();
<!--CRLF-->
21: configuration.Configure();
<!--CRLF-->
22: _sessionFactory = configuration.BuildSessionFactory();
<!--CRLF-->
23: }
<!--CRLF-->
24: return _sessionFactory;
<!--CRLF-->
25: }
<!--CRLF-->
26: }
<!--CRLF-->
27:
<!--CRLF-->
28: public static ISession OpenSession()
<!--CRLF-->
29: {
<!--CRLF-->
30: return SessionFactory.OpenSession();
<!--CRLF-->
31: }
<!--CRLF-->
32: }
<!--CRLF-->
33: }
<!--CRLF-->
下一步我们创建repositorys
PostRepository.cs
1: using System;
<!--CRLF-->
2: using System.Collections.Generic;
<!--CRLF-->
3: using System.Linq;
<!--CRLF-->
4: using System.Text;
<!--CRLF-->
5: using Core.Domain.Model;
<!--CRLF-->
6: using NHibernate;
<!--CRLF-->
7: using NHibernate.Criterion;
<!--CRLF-->
8:
<!--CRLF-->
9: namespace Core.Domain.Repositories
<!--CRLF-->
10: {
<!--CRLF-->
11: public class PostRepository: IRepository<post></post>
<!--CRLF-->
12: {
<!--CRLF-->
13: #region IRepository<post> Members</post>
<!--CRLF-->
14:
<!--CRLF-->
15: void IRepository<post>.Save(Post entity)</post>
<!--CRLF-->
16: {
<!--CRLF-->
17: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
18: {
<!--CRLF-->
19: using (ITransaction transaction = session.BeginTransaction())
<!--CRLF-->
20: {
<!--CRLF-->
21: session.Save(entity);
<!--CRLF-->
22: transaction.Commit();
<!--CRLF-->
23: }
<!--CRLF-->
24: }
<!--CRLF-->
25: }
<!--CRLF-->
26:
<!--CRLF-->
27: void IRepository<post>.Update(Post entity)</post>
<!--CRLF-->
28: {
<!--CRLF-->
29: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
30: {
<!--CRLF-->
31: using (ITransaction transaction = session.BeginTransaction())
<!--CRLF-->
32: {
<!--CRLF-->
33: session.Update(entity);
<!--CRLF-->
34: transaction.Commit();
<!--CRLF-->
35: }
<!--CRLF-->
36: }
<!--CRLF-->
37: }
<!--CRLF-->
38:
<!--CRLF-->
39: void IRepository<post>.Delete(Guid id)</post>
<!--CRLF-->
40: {
<!--CRLF-->
41: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
42: {
<!--CRLF-->
43: using (ITransaction transaction = session.BeginTransaction())
<!--CRLF-->
44: {
<!--CRLF-->
45: session.Delete(id);
<!--CRLF-->
46: transaction.Commit();
<!--CRLF-->
47: }
<!--CRLF-->
48: }
<!--CRLF-->
49: }
<!--CRLF-->
50:
<!--CRLF-->
51: Post IRepository<post>.GetById(Guid id)</post>
<!--CRLF-->
52: {
<!--CRLF-->
53: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
54: return session.CreateCriteria<post>().Add(Restrictions.Eq(<span style="color: #006080">"Id"</span>, id)).UniqueResult<post>();</post></post>
<!--CRLF-->
55: }
<!--CRLF-->
56:
<!--CRLF-->
57: Post IRepository<post>.GetAll()</post>
<!--CRLF-->
58: {
<!--CRLF-->
59: throw new NotImplementedException();
<!--CRLF-->
60: }
<!--CRLF-->
61:
<!--CRLF-->
62: #endregion
<!--CRLF-->
63: }
<!--CRLF-->
64: }
<!--CRLF-->
CategoryRepository.cs
1: using System;
<!--CRLF-->
2: using System.Collections.Generic;
<!--CRLF-->
3: using System.Linq;
<!--CRLF-->
4: using System.Text;
<!--CRLF-->
5: using Core.Domain.Model;
<!--CRLF-->
6: using NHibernate;
<!--CRLF-->
7: using NHibernate.Criterion;
<!--CRLF-->
8:
<!--CRLF-->
9: namespace Core.Domain.Repositories
<!--CRLF-->
10: {
<!--CRLF-->
11: public class CategoryRepository: IRepository<category></category>
<!--CRLF-->
12: {
<!--CRLF-->
13: #region IRepository<category> Members</category>
<!--CRLF-->
14:
<!--CRLF-->
15: void IRepository<category>.Save(Category entity)</category>
<!--CRLF-->
16: {
<!--CRLF-->
17: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
18: {
<!--CRLF-->
19: using (ITransaction transaction = session.BeginTransaction())
<!--CRLF-->
20: {
<!--CRLF-->
21: session.Save(entity);
<!--CRLF-->
22: transaction.Commit();
<!--CRLF-->
23: }
<!--CRLF-->
24: }
<!--CRLF-->
25: }
<!--CRLF-->
26:
<!--CRLF-->
27: void IRepository<category>.Update(Category entity)</category>
<!--CRLF-->
28: {
<!--CRLF-->
29: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
30: {
<!--CRLF-->
31: using (ITransaction transaction = session.BeginTransaction())
<!--CRLF-->
32: {
<!--CRLF-->
33: session.Update(entity);
<!--CRLF-->
34: transaction.Commit();
<!--CRLF-->
35: }
<!--CRLF-->
36: }
<!--CRLF-->
37: }
<!--CRLF-->
38:
<!--CRLF-->
39: void IRepository<category>.Delete(Guid id)</category>
<!--CRLF-->
40: {
<!--CRLF-->
41: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
42: {
<!--CRLF-->
43: using (ITransaction transaction = session.BeginTransaction())
<!--CRLF-->
44: {
<!--CRLF-->
45: session.Delete(id);
<!--CRLF-->
46: transaction.Commit();
<!--CRLF-->
47: }
<!--CRLF-->
48: }
<!--CRLF-->
49: }
<!--CRLF-->
50:
<!--CRLF-->
51: Category IRepository<category>.GetById(Guid id)</category>
<!--CRLF-->
52: {
<!--CRLF-->
53: using (ISession session = NHibernateHelper.OpenSession())
<!--CRLF-->
54: return session.CreateCriteria<category>().Add(Restrictions.Eq(<span style="color: #006080">"Id"</span>, id)).UniqueResult<category>();</category></category>
<!--CRLF-->
55: }
<!--CRLF-->
56:
<!--CRLF-->
57: Category IRepository<category>.GetAll()</category>
<!--CRLF-->
58: {
<!--CRLF-->
59: throw new NotImplementedException();
<!--CRLF-->
60: }
<!--CRLF-->
61:
<!--CRLF-->
62: #endregion
<!--CRLF-->
63: }
<!--CRLF-->
64: }
<!--CRLF-->
我们看到在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" ? >
<!--CRLF-->
2: hibernate-mapping xmlns ="urn:nhibernate-mapping-2.2"
<!--CRLF-->
3: namespace ="Core.Domain.Model"
<!--CRLF-->
4: assembly ="Core" >
<!--CRLF-->
5:
<!--CRLF-->
6: class name ="Category" table ="Categories" dynamic-update ="true" >
<!--CRLF-->
7: cache usage ="read-write" />
<!--CRLF-->
8: id name ="Id" column ="Id" type ="Guid" >
<!--CRLF-->
9: generator class ="guid" />
<!--CRLF-->
10: id >
<!--CRLF-->
11: property name ="Name" length ="100" />
<!--CRLF-->
12: class >
<!--CRLF-->
13: hibernate-mapping >
<!--CRLF-->
注意:一定要设置每个映射文件的简历动作为"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" >
<!--CRLF-->
2: session-factory >
<!--CRLF-->
3: property name ="connection.driver_class" > NHibernate.Driver.SqlClientDriver property >
<!--CRLF-->
4: property name ="connection.connection_string" > server=./SQLExpress;database=NHibernate101;Integrated Security=true; property >
<!--CRLF-->
5: property name ="show_sql" > true property >
<!--CRLF-->
6: property name ="dialect" > NHibernate.Dialect.MsSql2008Dialect property >
<!--CRLF-->
7: property name ="cache.use_query_cache" > false property >
<!--CRLF-->
8: property name ="adonet.batch_size" > 100 property >
<!--CRLF-->
9: property name ="proxyfactory.factory_class" > NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle property >
<!--CRLF-->
10: mapping assembly ="Infrastructure" />
<!--CRLF-->
11: session-factory >
<!--CRLF-->
12: hibernate-configuration >
<!--CRLF-->
十,测试
现在我们去测试我们的Nhibernate配置,通过测试我们添加一些数据到我们的"Categories"表,那么首先要引用Nbibernate程序集以及拷贝hibernate.cfg.xml到我们的测试项目下,添加如下引用:
1.Castle.Core
2.Castle.DynamicProxy2
3.Infrastructure
4.NHibernate
5.NHibernate.ByteCode.Castle
添加如下测试方法:
1: [TestMethod]
<!--CRLF-->
2: [DeploymentItem( "hibernate.cfg.xml" )]
<!--CRLF-->
3: public void CanCreateCategory()
<!--CRLF-->
4: {
<!--CRLF-->
5: IRepository<category> repo = <span style="color: #0000ff">new</span> CategoryRepository();</category>
<!--CRLF-->
6: Category category = new Category();
<!--CRLF-->
7: category.Name = "ASP.NET" ;
<!--CRLF-->
8:
<!--CRLF-->
9: repo.Save(category);
<!--CRLF-->
10:
<!--CRLF-->
11: }
<!--CRLF-->
运行我们的测试方法,我们将看到测试方法成功通过:
核查我们的数据库,查看category是否已经添加:
随下的文章中我们将继续探索!