一,摘要
在本篇文章中我们覆盖如何安装配置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.SqlClientDriverproperty>
4: <property name="connection.connection_string">server=./SQLExpress;database=NHibernate101;Integrated Security=true;property>
5: <property name="show_sql">trueproperty>
6: <property name="dialect">NHibernate.Dialect.MsSql2008Dialectproperty>
7: <property name="cache.use_query_cache">falseproperty>
8: <property name="adonet.batch_size">100property>
9: <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castleproperty>
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是否已经添加:
随下的文章中我们将继续探索!