zoukankan      html  css  js  c++  java
  • 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文件夹中如图:1

    配置的信息:

    <?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文件如图:

    2

    具体的如下代码:

       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这样:
    3
    就是勾选它的Create a strongly-typed view使用的Model class 就是我们的Employee类,这样写可以帮组我们省了一堆事,当然了,这里我们仅仅是一个CURD的列子,具体的还要看具体的业务需求。这里特别注意在选着Scaffold template时,要选着我们对应的CURD操作,这里的Index是一个List。其他的一一对应!
    controllers中的EmployeeControllers对应的Views就是这样了:
    4
     
     
    最后的补充:

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

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

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

  • 相关阅读:
    服务器使用ssh秘钥登录并禁止密码登录
    c# @符号后面对双引号(")转义
    unity EditorWindow拖入文件或文件夹
    unity 生成GUID
    unity 将对象始终放在鼠标位置和指定的相机z轴位置
    unity 打开指定路径文件夹
    unity UTF8格式加载和保存xml
    VsCode 手动配置omnisharp、.NET Core Debugger、razor
    Maya 保存场景时UV和UV集丢失
    进程通信机制
  • 原文地址:https://www.cnblogs.com/struCoder/p/3603480.html
Copyright © 2011-2022 走看看