ASP.NET MVC中使用Nhibernate(一)

时间:2022-02-21 13:16:06

一,摘要

在本篇文章中我们覆盖如何安装配置Nhibernate,以及在MVC中如何使用它.

二,什么是Nhibernate

Nhibernate是一个应用于.NET中的对象-关系映射器,它将对象模型映射到关系型数据库,在本文中你将看到Nhibernate处理大部分持久层相关联的任务,从http://sourceforge.net/projects/nhibernate/files/站点下载Nhibernate

三,安装Nhibernate

下载压缩包,并且解压到你的电脑上,这样就安装好了.

四,创建ASP.NET MVC项目

创建一个新的MVC项目,伴随着单元测试项目.添加两个类库:Infrastructure与Core.这是一个非常简单的模型帮助我们理解Nhibernate是如何工作的:一个博客帖子属于一个或者多个类别,一个类别可能拥有一个或者多个帖子
ASP.NET MVC中使用Nhibernate(一)
我们将使用SQL Server2008速成版创建我们的数据库,当然也可以在Visual Studio里创建模型,然后通过编写Nhibernate配置去创建数据库.

五,创建模型

下一步去创建我们的模型,它是我们的数据库面向对象的表现,我们将使用Visual Studio的类设计器创建它
ASP.NET MVC中使用Nhibernate(一)

六,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:       }
运行我们的测试方法,我们将看到测试方法成功通过:
ASP.NET MVC中使用Nhibernate(一)
核查我们的数据库,查看category是否已经添加:
ASP.NET MVC中使用Nhibernate(一)

随下的文章中我们将继续探索!