65.9K
CodeProject 正在变化。 阅读更多。
Home

NHibernate – 简介、配置与 MVC 的 CRUD 操作

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (16投票s)

2017年4月2日

CPOL

4分钟阅读

viewsIcon

66105

downloadIcon

2115

本实践演示了 NHibernate 的基础知识,并通过一个示例 CRUD 应用程序展示了如何将 NHibernate 集成到 .Net 和 MVC 环境中。

引言

本教程更侧重于实际操作,讲解如何将 NHibernate 框架集成到 MVC6 .Net 环境中,演示将包含以下部分:

  • 安装 NHibernate
  • 定义一个简单的业务对象类。
  • 创建 NHibernate 映射以加载和保存业务对象。
  • 配置 NHibernate 以连接数据库。
  • 在 MVC 项目中编写简单的 CRUD 代码

示例项目

我将创建的示例 MVC 6 项目在 SQL Server 本地数据库中包含一个表,我们将使用 NHibernate 执行 CRUD 操作。(本教程的范围是设置 MVC 6 和 NHibernate 的环境,因此为了保持简单,我们将只有一个表,没有关系。)此解决方案是单个项目,MVC 控制器直接访问 NHibernate,这在实际项目中可能不被推荐。

背景

NHibernate 简介

NHibernate 是一个开源的对象关系映射技术,适用于 .Net Framework。它提供了将域模型(类)映射到传统关系数据库并生成查询所需的框架。要了解更多关于 NHibernate 的信息,请访问 http://nhibernate.info/

在本文中,我将更多地关注 NHibernate 及其如何集成到 MVC 中。在继续学习本教程之前,需要了解 .Net 和 MVC 知识。

使用代码

数据库

在本地 SQL Server 数据库中创建一个名为BookStoreDB的数据库。创建一个名为Book的表,如下所示:

CREATE TABLE [dbo].[Book] (
    [Id]          BIGINT        IDENTITY (1, 1) NOT NULL,
    [Title]       VARCHAR (50)  NULL,
    [Author]      VARCHAR (50)  NULL,
    [Genre]       VARCHAR (50)  NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

NHibernate sample table

创建项目

让我们开始在 Visual Studio 中创建项目。添加一个名为Swinkaran.Nhbnt.Web的 ASP.Net Web 应用程序项目,使用 MVC 模板。在本教程中,我们将添加新的库和文件。下面的屏幕截图显示了将添加到项目中的文件,稍后在本教程中我们将讨论这些文件的每一个。

 

安装 NHibernate

现在,我们已经创建了 NHibernate。可以通过 NuGet 包管理器进行安装。有多种方法可以安装 NuGet .Net Framework。我将展示两种最常见的通过 NuGet 安装 Nhibernare 的方法。

1. NuGet 包管理器

转到 NuGet 包管理器并按如下方式安装:

2. 程序包管理器控制台

转到程序包管理器控制台并键入以下内容:

PM> install-package NHibernate

要了解有关 NuGet 包和安装的更多信息,请访问 NuGet 文档:https://docs.microsoft.com/en-us/nuget/guides/install-nuget

除了上述通过 NuGet 包使用的方法外,开发人员还可以从 http://nhibernate.info/ 下载 NHibernate 库。

就是这样。我们已经完成了将 NHibernate 集成到我们的 MVC6 项目中。

创建 NHibernate 配置文件

现在,我们已经创建了数据库和表,并安装了必要的库来处理 NHibernate。让我们将 .Net 应用程序与数据库连接起来,以便应用程序能够连接到数据库。我使用 NHibernate 配置文件来实现这一点。此配置文件包含连接应用程序到数据库所需的信息。

Models文件夹下创建一个 XML 或 config 文件,命名为hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">
      NHibernate.Connection.DriverConnectionProvider
    </property>
    <property name="connection.driver_class">
      NHibernate.Driver.SqlClientDriver
    </property>
    <property name="connection.connection_string">
      Server=(localdb)\MSSQLLocalDB;database=BookStoreDB;Integrated Security=SSPI;
    </property>
    <property name="dialect">
      NHibernate.Dialect.MsSql2012Dialect
    </property>
  </session-factory>
</hibernate-configuration>

创建模型类

Models文件夹下创建一个名为Book的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Swinkaran.Nhbnt.Web.Models
{
    public class Book
    {
        public virtual long Id { get; set; }
        public virtual string Title { get; set; }
        public virtual string Author { get; set; }
        public virtual string Genre { get; set; }
    }
}

创建映射文件

创建一个名为 Mappings 的文件夹,并创建一个新的 XML 文件,命名为Book.hbm.xml。重要的是文件名为hbm,这是文件名的一部分,表示该文件是映射文件。为此 XML 文件将**生成操作**设置为“**嵌入的资源**”。此文件的目的是在模型类和数据库中的相应表之间创建映射。

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="Swinkaran.Nhbnt.Web" namespace="Swinkaran.Nhbnt.Web.Models">
  <class name="Book" table="Book" dynamic-update="true" >
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="long">
      <generator class="native" />
    </id>

    <property name="Title"  />
    <property name="Author" />
    <property name="Genre" />
  </class>
</hibernate-mapping>

管理 NHibernate 会话

创建一个名为NhibernateSession.cs的类。

namespace Swinkaran.Nhbnt.Web
{
    public class NHibernateSession
    {
        public static ISession OpenSession()
        {
            var configuration = new Configuration();
            var configurationPath = HttpContext.Current.Server.MapPath(@"~\Models\hibernate.cfg.xml");
            configuration.Configure(configurationPath);
            var bookConfigurationFile = HttpContext.Current.Server.MapPath(@"~\Mappings\Book.hbm.xml");
            configuration.AddFile(bookConfigurationFile);
            ISessionFactory sessionFactory = configuration.BuildSessionFactory();
            return sessionFactory.OpenSession();
        }
    }
}

添加控制器

添加一个名为BookController的新控制器。BookController非常简单基础。它定义了对 Book 实体执行创建、读取、更新和删除(CRUD)功能的方法。这些方法中的每一个都利用 NHibernate 会话来初始化和打开一个会话,并执行必要的事务。

namespace Swinkaran.Nhbnt.Web.Controllers
{
    public class BookController : Controller
    {
        // GET: Book
        public ActionResult Index()
        {
            ViewBag.Message = "Your application description page.";
            IList<Book> books;

            using (ISession session = NHibernateSession.OpenSession())  // Open a session to conect to the database
            {
                books = session.Query<Book>().ToList(); //  Querying to get all the books
            }

            return View(books);
        }

        // GET: Book/Details/5
        public ActionResult Details(int id)
        {
            Book book = new Book();
            using (ISession session = NHibernateSession.OpenSession())
            {
                book = session.Query<Book>().Where(b => b.Id == id).FirstOrDefault();
            }

            return View(book);
        }

        // GET: Book/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Book/Create
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                Book book = new Book();     //  Creating a new instance of the Book
                book.Title = collection["Title"].ToString();
                book.Genre = collection["Genre"].ToString();
                book.Author = collection["Author"].ToString();

                // TODO: Add insert logic here
                using (ISession session = NHibernateSession.OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())   //  Begin a transaction
                    {
                        session.Save(book); //  Save the book in session
                        transaction.Commit();   //  Commit the changes to the database
                    }
                }
                return RedirectToAction("Index");
            }
            catch (Exception e)
            {
                return View();
            }
        }

        // GET: Book/Edit/5
        public ActionResult Edit(int id)
        {
            Book book = new Book();
            using (ISession session = NHibernateSession.OpenSession())
            {
                book = session.Query<Book>().Where(b => b.Id == id).FirstOrDefault();
            }

            ViewBag.SubmitAction = "Save";
            return View(book);
        }

        // POST: Book/Edit/5
        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            try
            {
                Book book = new Book();
                book.Id = id;
                book.Title = collection["Title"].ToString();
                book.Genre = collection["Genre"].ToString();
                book.Author = collection["Author"].ToString();


                // TODO: Add insert logic here
                using (ISession session = NHibernateSession.OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())
                    {
                        session.SaveOrUpdate(book);
                        transaction.Commit();
                    }
                }
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        // GET: Book/Delete/5
        public ActionResult Delete(int id)
        {
            // Delete the book
            Book book = new Book();
            using (ISession session = NHibernateSession.OpenSession())
            {
                book = session.Query<Book>().Where(b => b.Id == id).FirstOrDefault();
            }
            ViewBag.SubmitAction = "Confirm delete";
            return View("Edit", book);
        }

        // POST: Book/Delete/5
        [HttpPost]
        public ActionResult Delete(long id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
                using (ISession session = NHibernateSession.OpenSession())
                {
                    Book book = session.Get<Book>(id);

                    using (ITransaction trans = session.BeginTransaction())
                    {
                        session.Delete(book);
                        trans.Commit();
                    }
                }
                return RedirectToAction("Index");
            }
            catch (Exception e)
            {
                return View();
            }
        }
    }
}

BookController 类演示了如何使用已创建的 NHibernate 会话执行 CRUD 操作。

以下是输出项目。好吧,我没有花太多时间解释如何创建每个视图和样式设置,因为这是一个非常基础的 MVC6 项目。但是,下载文件包含了所有必需的源文件,包括完成的 MVC6 项目和下面输出中显示的样式。

历史

初始版本: 02/04/2017

包含源代码 : 03/04/2017 

© . All rights reserved.