ASP.NET MVC+NHibernate (CURD)

今天的这篇博文是关于在ASP.NET MVC 中使用Nhibernate并且对其session进行管理。当你阅读这篇博文时,默认你已经熟悉Nhibernate和ASP.NET MVC。其实在.net中有一款ORM框架:Entity Framework。我个人觉得在企业级项目中使用EF框架并不如使用NHibernate好,况且hibernate在jsp中已经是运用的十分的好了,Nhibernate只不过是将应用平台拓展到.net中。

首先呢,建立一个MVC的工程。这个在这就不截图了,总所周知使用NHIbernate要进行配置。我们在此将配置文件放在Models下的Nhibernate文件夹中如图:

配置的信息:

<?xml version="1.0" encoding="utf-8"?>
 
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">
      Server=(local);initial catalog=Mvc_test;Integrated Security=SSPI
    </property>
    <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
    <property name="show_sql">false</property>
    <property name="hbm2ddl.auto">update</property>
    <property name="adonet.batch_size">10</property>
    <property name="command_timeout">60</property>
    <property name="current_session_context_class">web</property><!--这个地方很重要,没有这句话,会报 No current session 当绑定的时候-->
    <!--Mapping-->
    <mapping resource="Ebuy.Website.Models.Nhibernate.Employee.hbm.xml" assembly="Ebuy.Website" file=""/>
  </session-factory>
</hibernate-configuration>

正如我在配置文件中的注释一样,那句话十分的重要,没有那句话项目运行会报错,报错的原因也是(大概意思):没有上下文的session

在上面的配置文件中我将要映射的类文件也写在上面了,当然你也可以在SessionFactory中进行添加,我个人认为这样写比较方便管理,并且一目了然,纯属个人习惯吧。到目前为止我们将配置文件配好了,对了!一个十分重要并且很容易被遗忘的步骤:在配置文件配好了以后一定要将其xml属性的Copy to output Directory设置为:Copy always。不然一会报错。接着我们Employee类进行mapping.我们想把Employee类写出来吧:

 public class Employee
    {
        public virtual int? Id { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Designation { get; set; }
    }

其映射代码为:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Ebuy.Website" namespace="Ebuy.Website.Models">
  <class name="Employee" table="Employee" dynamic-update="true">
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="int">
      <generator class="native"/>
    </id>
    <property name="FirstName" column="FirstName" length="20"/>
    <property name="LastName" column="LastName" length="20" />
    <property name="Designation" column="Designation" length="50"/>
  </class>
</hibernate-mapping>

恩,好了到目前为止,我们将最为基础的步骤走完了,几下来的几个步骤是十分的重要,我也是在网上找了一个遍加上个人的想法综合得到的,如果有什么不对的地方欢迎指出。同时:show me your code!

如上面的截图一样,我们在Models下有一个SessionManagement.cs文件。这个类是对Session的管理。这个类继承了ActionFilterAttribute.所以我们可以重写onActionExecution和onActionExecuted.具体的请看贴出的代码;

using System;
using System.Web;
using System.Web.Mvc;
using NHibernate;
using NHibernate.Context;
 
namespace Ebuy.Website.Models
{
    public class SessionManagement:ActionFilterAttribute
    {
        public SessionManagement()
        {
            SessionFactory = MvcApplication.SessionFactory;
        }
        private ISessionFactory SessionFactory { get; set; }
        public ISession _session;
 
        //当web程序执行一个action时
 
        public override void OnActionExecuting(ActionExecutingContext actionContext)
        {
            //打开session
            _session = SessionFactory.OpenSession();
            //绑定当前的session
            CurrentSessionContext.Bind(_session);
            //开始执行一个事务
            _session.BeginTransaction();
        }
 
        
        //当一个web程序执行完action时的操作
        public override void OnActionExecuted(ActionExecutedContext acionExcutedContext)
        {
            //获取当前的session
            _session = SessionFactory.GetCurrentSession();
            //获取当前session的事务
            var transaction = _session.Transaction;
            if (transaction != null && transaction.IsActive)
            {
                //提交事务
                transaction.Commit();
            }
            //将当前的session从当前的SessionFactory解绑
            _session = CurrentSessionContext.Unbind(SessionFactory);
            //关闭session
            _session.Close();
            _session.Dispose();
        }
    }
}

或许大家在这里会问在构造函数里MvcApplicaction怎么会有SessionFactory这个属性。大家别急,我在这讲讲我实现对Session管理的思路。我们可以在程序启动时,就立即建立一个sessionFactory以便对session的管理,同时呢,我们可以运用memcached对Nhibernate进行二级缓存的管理,当然了这也是后话了。同时找到Nhibernate的config文件。这是我的Global.asax文件:

namespace Ebuy.Website
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801
 
    public class MvcApplication : System.Web.HttpApplication
    {
        public static ISessionFactory SessionFactory { get; private set; }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
            InitializeSessionFactory();
        }
        private void InitializeSessionFactory()
        {
            var configuration = new Configuration();
            var configurationPath = HttpContext.Current.Server.MapPath(@"~/Models/Nhibernate/hibernate.cfg.xml");
            SessionFactory = configuration.Configure(configurationPath).BuildSessionFactory();
        }
    }
}

好了,我们进行到这,就还有最后一个步骤了,就是实现CURD,我们在Controllers中创建一个cs文件如图:

具体的如下代码:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.Mvc;
   6:  using NHibernate;
   7:  using Ebuy.Website.Models;
   8:   
   9:  namespace Ebuy.Website.Controllers
  10:  {
  11:      
  12:      public class EmployeeController : Controller
  13:      {
  14:          //
  15:          // GET: /Employee/
  16:          
  17:          [SessionManagement]
  18:          public ActionResult Index()
  19:          {
  20:              //在这里为什么写的和下面的不同的原因:在SessionManagement中已经将一个Session绑定到当前的
  21:              //线程中,所以在这里可以通过GetCurrentSession()来获得当前已经打开的session
  22:              ISession _session = MvcApplication.SessionFactory.GetCurrentSession();
  23:              var employees = _session.CreateQuery("from Employee").List<Employee>();
  24:              return View(employees);  
  25:          }
  26:   
  27:         // [SessionManagement]
  28:          public ActionResult Create()
  29:          {
  30:              return View();
  31:          }
  32:   
  33:   
  34:          [HttpPost,SessionManagement]
  35:          public ActionResult Create(Employee employee)
  36:          {
  37:              int isSave = new NHibernateRespository().Create(employee);
  38:              if (isSave > 0)
  39:              {
  40:                  return RedirectToAction("Index");
  41:              }
  42:              return View();
  43:          }
  44:   
  45:          [SessionManagement]
  46:          public ActionResult Edit(int id)
  47:          {
  48:              var employee = new NHibernateRespository().Get(id);
  49:              return View(employee);
  50:          }
  51:   
  52:          [HttpPost,SessionManagement]
  53:          public ActionResult Edit(int id, Employee employee)
  54:          {
  55:              try
  56:              {
  57:                  new NHibernateRespository().Edit(id, employee);
  58:                  return RedirectToAction("Index");
  59:              }
  60:              catch (Exception ex)
  61:              {
  62:                  return View();
  63:              }
  64:              
  65:          }
  66:   
  67:          [SessionManagement]
  68:          public ActionResult Details(int id)
  69:          {
  70:              var employee = new NHibernateRespository().Get(id);
  71:              return View(employee);
  72:   
  73:          }
  74:   
  75:          [SessionManagement]
  76:          public ActionResult Delete(int id)
  77:          {
  78:              var employee = new NHibernateRespository().Get(id);
  79:              return View(employee);
  80:          }
  81:   
  82:          [HttpPost,SessionManagement]
  83:          public ActionResult Delete(int id, Employee employee)
  84:          {
  85:              try
  86:              {
  87:                  new NHibernateRespository().Delete(id, employee);
  88:                  return RedirectToAction("Index");
  89:              }
  90:              catch (Exception ex)
  91:              {
  92:                  return View();
  93:              }
  94:   
  95:          }
  96:   
  97:      }
  98:  }
重要的解释,我已经在代码中注释了。
在这里,是一个整体的controllers。那我们在创建Index时,要创建它的view这样:
就是勾选它的Create a strongly-typed view使用的Model class 就是我们的Employee类,这样写可以帮组我们省了一堆事,当然了,这里我们仅仅是一个CURD的列子,具体的还要看具体的业务需求。这里特别注意在选着Scaffold template时,要选着我们对应的CURD操作,这里的Index是一个List。其他的一一对应!
controllers中的EmployeeControllers对应的Views就是这样了:
 
 
最后的补充:

在上面的列子中,我们实现了最为简单的CURD,本文不是着重于CURD,本文的意义在于在ASP.NET MVC 中使用NHibernate并且对其Session进行管理,以便达到最好的使用效果,毕竟打开一个openSession()是要占用资源了。

在博文中如果有不对或者有所欠缺的地方,欢迎各位园友指出,本人也在不断的学习中。如有问题email me!

本文属于原创博文,允许转载,但是请保留原文的连接!

ASP.NET MVC+NHibernate (CURD),古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。