ASP.NET 的 NHibernate 设置






4.90/5 (19投票s)
了解如何在 ASP.NET 应用程序中配置 NHibernate
引言
NHibernate 是一个相当流行的框架,用于抽象和处理持久化层。即使在今天,随着 Entity Framework 的出现,NHibernate 因其成熟度和资源丰富性,仍然是许多开发者的首选。
本文旨在提供一个基本的 ASP.NET 应用程序,作为任何希望从零开始开发的人的基础。本文提供了这个基本应用程序,其中包含一个小实体,并详细解释了 NHibernate 是如何在应用程序中设置的。
以下是成功设置 NHibernate 所需执行的步骤:
- 创建一个空白的 ASP.NET 项目。
- 通过 NuGet 导入所需的 DLL。
- 创建用于创建和处理 NHibernate 会话和操作的类。
- 在 Web.Config 文件中配置 NHibernate 和 Log4net。可选地,Log4net 可以记录 NHibernate 的日志,这将在本文中演示。
- 在 Global.asax 中配置 NHibernate 会话。
- 在 hbm.xml 文件中创建实体的映射,以及它们各自的值对象类文件。
- 在 Web.Config 文件中,使用下载的应用程序中声明的设置创建一个数据库。该数据库连接字符串名为
DatabaseConnectionString
,可以在connectionStrings
标签中找到。
在回顾了以上主题后,将提供如何执行应用程序的简要说明。最后,本文将以对 NHibernate 及其优缺点的小讨论结束。
这里需要做一个小说明:代码完全使用 Microsoft Web Developer 2010 开发。
设置 NHibernate
创建空白项目并导入所需 DLL
为了开始开发,需要创建一个空的 ASP.NET 空 Web 应用程序,通过 NuGet 导入所需的 DLL,并创建必要的文件。由于这些步骤非常直接,而且不是本文的重点,因此将不在此演示。本文提供的示例可下载项目可作为初始开发的基准模板。不过,这里有三个相关的注意事项:
- 通过 NuGet 导入的 DLL 是:
- 需要通过以下步骤添加对
System.Transactions
的引用:
-
- 在 解决方案资源管理器 中,右键单击
引用
元素,然后选择 添加引用... - 选择 .NET 选项卡,然后选择
System.Transactions
项。 - 按 OK,此引用将被导入到项目中。
- 在 解决方案资源管理器 中,右键单击
- 每当添加一个 hbm.xml 文件时,对于这种设置,将其设置为 嵌入资源 非常重要。这是强制性的,因为通过这样做,NHibernate 框架可以轻松找到这些资源。为此,请按照以下步骤操作:
-
- 在 解决方案资源管理器 中,右键单击文件,然后单击 属性。
- 在 生成操作 部分,选择 嵌入资源 。
- 按 Ctrl+S 保存此配置。
处理 NHibernate 的基本类
现在项目已设置好,必须定义用于使用 NHibernate 的类。它们是 NHibernateHelper
和 SessionHelper
,均在下载项目中的 NHibernate 目录下创建。
下面是 NHibernateHelper
的代码:
using System;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Context;
namespace WebAppBasicNHibernate.NHibernate
{
/// <summary>
/// Here basic NHibernate manipulation methods are implemented.
/// </summary>
public class NHibernateHelper
{
private ISessionFactory _sessionFactory = null;
/// <summary>
/// In case there is an already instantiated NHibernate ISessionFactory,
/// retrieve it, otherwise instantiate it.
/// </summary>
public ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
Configuration configuration = new Configuration();
configuration.Configure();
// build a Session Factory
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
/// <summary>
/// Open an ISession based on the built SessionFactory.
/// </summary>
/// <returns>Opened ISession.</returns>
public ISession OpenSession()
{
return SessionFactory.OpenSession();
}
/// <summary>
/// Create an ISession and bind it to the current tNHibernate Context.
/// </summary>
public void CreateSession()
{
CurrentSessionContext.Bind(OpenSession());
}
/// <summary>
/// Close an ISession and unbind it from the current
/// NHibernate Context.
/// </summary>
public void CloseSession()
{
if (CurrentSessionContext.HasBind(SessionFactory))
{
CurrentSessionContext.Unbind(SessionFactory).Dispose();
}
}
/// <summary>
/// Retrieve the current binded NHibernate ISession, in case there
/// is any. Otherwise, open a new ISession.
/// </summary>
/// <returns>The current binded NHibernate ISession.</returns>
public ISession GetCurrentSession()
{
if (!CurrentSessionContext.HasBind(SessionFactory))
{
CurrentSessionContext.Bind(SessionFactory.OpenSession());
}
return SessionFactory.GetCurrentSession();
}
}
}
此类通过访问 Web.Config 文件中的数据来配置 NHibernate。这是在 SessionFactory
属性中完成的。基本上,使用无参数的 Configuration.Configure()
方法,框架会从 Web.Config 文件中获取配置数据。另外请注意,会话存储在名为 _sessionFactory
的 static
ISessionFactory
对象中。每当再次调用 SessionFactory
属性时,如果已存在 _sessionFactory
对象,则不会创建新实例,因此会使用已存在的实例。请注意,这里实现了单例设计模式。这样做的原因是构建 ISessionFactory
对象成本很高,因此使用单例非常优雅。
NHibernateHelper
类中的其他方法仅用于操作会话。接下来,查看 SessionHelper
类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NHibernate;
namespace WebAppBasicNHibernate.NHibernate
{
/// <summary>
/// Helper methods for dealing with NHibernate ISession.
/// </summary>
public class SessionHelper
{
/// <summary>
/// NHibernate Helper
/// </summary>
private NHibernateHelper _nHibernateHelper = null;
public SessionHelper()
{
_nHibernateHelper = new NHibernateHelper();
}
/// <summary>
/// Retrieve the current ISession.
/// </summary>
public ISession Current
{
get
{
return _nHibernateHelper.GetCurrentSession();
}
}
/// <summary>
/// Create an ISession.
/// </summary>
public void CreateSession()
{
_nHibernateHelper.CreateSession();
}
/// <summary>
/// Clear an ISession.
/// </summary>
public void ClearSession()
{
Current.Clear();
}
/// <summary>
/// Open an ISession.
/// </summary>
public void OpenSession()
{
_nHibernateHelper.OpenSession();
}
/// <summary>
/// Close an ISession.
/// </summary>
public void CloseSession()
{
_nHibernateHelper.CloseSession();
}
}
}
此类仅作为 NHibernateHelper
的包装器。您甚至可以选择不实现它,直接使用 NHibernateHelper
本身,但是您可能会发现这个包装器很有用。
在 Web.Config 中配置 NHibernate 数据库设置和 Log4Net
在基本设置完成后,需要配置 NHibernate 数据库设置,以及可选的 Log4net。由于 Web.Config 文件相当小,因此将在下面完整显示。
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<configSections>
<!-- Declaration for NHibernate and Log4Net sections -->
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<connectionStrings>
<add name="DatabaseConnectionString"
connectionString="User ID=eduardo;Password=eduardo;
Data Source=.\SQLExpress; Initial Catalog=NHibernateBasic" />
</connectionStrings>
<!-- Log4Net config -->
<log4net>
<logger name="WebAppBasicNHibernateLogger">
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</logger>
<logger name="NHibernate.SQL">
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</logger>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString"
value="c:\LogWebAppBasicNHibernate\Log-" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="25" />
<maximumFileSize value="20MB" />
<datePattern value="yyyy-MM-dd'.log'" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
<!-- NHibernate configuration -->
<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_name">DatabaseConnectionString</property>
<property name="show_sql">true</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<!-- Create Database -->
<property name="hbm2ddl.auto">update</property>
<property name="current_session_context_class">web</property>
<mapping assembly="WebAppBasicNHibernate" />
</session-factory>
</hibernate-configuration>
<system.web>
<customErrors mode="Off"/>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
在 configSections
标签中,可以看到 NHibernate 和 Log4net 部分的声明。另外,请注意,在 connectionStrings
标签中有一个名为 DatabaseConnectionString
的连接字符串,它用于 NHibernate 数据库配置。
如果查看 log4net
标签,您会看到 Log4net 的配置设置。名为 WebAppBasicNHibernateLogger
的日志记录器用于记录应用程序的事件,而 NHibernate.SQL
用于记录 NHibernate 的事件。请注意,NHibernate.SQL
的调试级别设置为 DEBUG,这将记录所有运行的查询。最后,为此,请注意 WebAppBasicNHibernateLogger
和 NHibernate.SQL 都使用 LogFileAppender
作为其日志记录机制,该机制基本上将数据记录到磁盘文件,其设置位于其配置中。
hibernate-configuration
标签之间可以找到 NHibernate 的设置。可以看到使用了 DatabaseConnectionString
,选择了 Microsoft SQL Server 方言,Assembly
名称与应用程序匹配,数据库将自动更新(因为 hbm2ddl.auto
标签设置为 update),最后 SQL 查询被配置为显示(因为 show_sql
标签设置为 true
)。这是 NHibernate 配置的核心。在这里,您可以更改正在使用的连接字符串、SQL 语言、数据模型的程序集、数据库的更新方式等等。因此,请特别注意这些设置,并学会如何正确更改它们。
最后,需要强调的是,要运行可下载的应用程序,必须创建一个数据库,其设置与此连接字符串 DatabaseConnectionString
中声明的设置相符。请注意,您可以根据需要更改这些设置。此外,可下载应用程序已使用 SQL Server 2008 Express Edition 进行测试。
在 Global.asax 中设置 NHibernate 会话
这可能是 NHibernate 设置中最关键的部分。如果选择对实体使用 延迟加载,则必须在此处相应地使用会话的打开和关闭。
为了支持 延迟加载,NHibernate 需要在请求开始时打开 Session
,并在请求结束时关闭它。因此,Global.asax 是执行此操作的正确位置,因为它捕获了请求打开和关闭的所有事件。下面显示了执行上述操作的代码:
protected SessionHelper _sessionHelper = null;
..............
protected void Application_BeginRequest(object sender, EventArgs e)
{
_sessionHelper = new SessionHelper();
_sessionHelper.OpenSession();
}
protected void Application_EndRequest(object sender, EventArgs e)
{
_sessionHelper = new SessionHelper();
_sessionHelper.CloseSession();
}
请注意,在 Global.asax 文件中设置 NHibernate 的 Session
是多么直接,对于 延迟加载 来说。只需捕获请求开始事件,打开会话,捕获请求结束事件,最后关闭 Session
。请注意,每次打开或关闭 Session
时都会创建一个新对象,但这对于性能无关紧要,因为 ISessionFactory
本身在 NHibernateHelper
类中被视为单例。
最后一点是关于 Log4net,它在应用程序启动时进行初始化,如下所示:
protected void Application_Start(object sender, EventArgs e)
{
// start log4net
XmlConfigurator.Configure();
....
}
到这里就可以结束阅读本文了,因为关于设置 NHibernate 所需的一切都已解释清楚。接下来将展示如何创建 NHibernate 实体、数据访问对象 (DAO),以及讨论一些其他有趣的话题。
创建从数据库映射的实体
为了开始使用 NHibernate,首先需要创建将数据库表映射到值对象的实体。为此,需要创建一个类来表示值对象,并将其映射到 XML 文件中,通常命名为:FILE_NAME.hbm.xml 。这里将重复本文中已经说过的一点:hbm.xml 文件必须配置为嵌入资源,应用程序才能按本文所述工作。
下载的应用程序附带了一个小机制,可以在创建实体和数据访问对象 (DAO) 时重用代码。这个机制,正如将要演示的那样,非常简单,但可以节省大量的编码工作。下面是它的类图:
基本上,该机制使用了两个类:BaseVo
和 BaseDao
。所有实体都应继承自 BaseVo
,所有数据访问对象 (DAO) 都应继承自 BaseDao
。BaseVo
包含 Id
属性,该属性用作所有实体的标识符。其类型是泛型的,因此在 BaseVo
子类化时定义。将此 Id
放在基类中,可以避免每个实体都定义其标识符的需要。此外,BaseVo
及其标识符在 BaseDao
中使用,后者实现了对所有 NHibernate 数据访问对象都有用的方法。通过让所有 DAO 继承自基类,所有这些方法都可以重用。
由于本文仅旨在描述基本的 NHibernate 设置,因此这里将只创建一个实体及其映射,并提供一些数据库交互的示例:Person
和 PersonDao
,正如您在类图中看到的。
现在,看一下 BaseVo
类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebAppBasicNHibernate.Vo
{
/// <summary>
/// Base Value Object class.
/// </summary>
/// <typeparam name="TIdentifier">Identifier Generic Type to be assigned dynamically.</typeparam>
public class BaseVo<TIdentifier>
where TIdentifier : new()
{
/// <summary>
/// Gets or sets the Identifier.
/// </summary>
public virtual TIdentifier Id { get; set; }
}
}
请注意此类多么直接。也请注意泛型标识符的使用。接下来,看一下 BaseDao
类:
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using NHibernate;
using NHibernate.Linq;
using WebAppBasicNHibernate.NHibernate;
using WebAppBasicNHibernate.Vo;
namespace WebAppBasicNHibernate.Dao
{
public class BaseDao<TEntity, TIdentifier>
where TIdentifier : new()
where TEntity : BaseVo<TIdentifier>
{
/// <summary>
/// NHibernate ISession to be used to manipulate data in the
/// database.
/// </summary>
protected ISession CurrentSession { get; set; }
public BaseDao()
{
SessionHelper sessionHelper = new SessionHelper();
CurrentSession = sessionHelper.Current;
}
/// <summary>
/// Load an Entity by its identifier.
/// </summary>
/// <param name="id">Entity´s identifier.</param>
/// <returns>Entity Object.</returns>
public TEntity LoadById(TIdentifier id)
{
TEntity entity = CurrentSession.Get<TEntity>(id);
return entity;
}
/// <summary>
/// Create an Entity.
/// </summary>
/// <param name="entity">Entity to be created.</param>
/// <returns>Identifier of the created Entity.</returns>
public TIdentifier Create(TEntity entity)
{
TIdentifier identifier = new TIdentifier();
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required))
{
identifier = (TIdentifier)CurrentSession.Save(entity);
transaction.Complete();
}
return identifier;
}
/// <summary>
/// Save or Update an Entity.
/// </summary>
/// <param name="entity">Entity to be saved or updated.</param>
public void SaveOrUpdate(TEntity entity)
{
TIdentifier identifier = new TIdentifier();
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required))
{
CurrentSession.SaveOrUpdate(entity);
transaction.Complete();
}
}
/// <summary>
/// Update an existing Entity.
/// </summary>
/// <param name="entity">Entity to be updated.</param>
public void Update(TEntity entity)
{
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required))
{
CurrentSession.Update(entity);
CurrentSession.Flush();
transaction.Complete();
}
}
/// <summary>
/// Delete an Entity based on its Instance.
/// </summary>
/// <param name="entity">Entity Instance.</param>
public void Delete(TEntity entity)
{
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required))
{
CurrentSession.Delete(entity);
transaction.Complete();
}
}
/// <summary>
/// Delete an Entity based on its Identifier.
/// </summary>
/// <param name="entityIdentifier">Entity Identifier.</param>
public void DeleteById(TIdentifier entityIdentifier)
{
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required))
{
TEntity entity = LoadById(entityIdentifier);
CurrentSession.Delete(entity);
transaction.Complete();
}
}
/// <summary>
/// Retrieve all Entities from the database.
/// </summary>
/// <returns>List of all entities.</returns>
public IList<TEntity> LoadAll()
{
return CurrentSession.Query<TEntity>().ToList();
}
}
}
请注意此类如何使用泛型来收集实体标识符和实体本身。另请参阅实体泛型必须继承自 BaseVo
,这使得该机制更加健壮。此外,许多有用的方法都是使用 NHibernate API 实现的,并结合泛型实体和标识符。每当一个类继承自 BaseDao
时,这些泛型值将自动填充,并且方法将对该类非常有用。
最后,请看下面的 Person
和 PersonDao
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebAppBasicNHibernate.Vo
{
public class Person : BaseVo<Int64>
{
public virtual String Name { get; set; }
public virtual Int32 Age { get; set; }
}
}
using System;
using WebAppBasicNHibernate.Vo;
using System.Collections.Generic;
using NHibernate.Linq;
namespace WebAppBasicNHibernate.Dao
{
public class PersonDao : BaseDao<Person, Int64>
{
public void DeleteByName(String name)
{
var queryResult = CurrentSession.QueryOver<Person>()
.Where(p => p.Name == name);
if (queryResult != null && queryResult.RowCount() > 0)
{
IList<Person> peopleToBeDeleted = queryResult.List();
peopleToBeDeleted.ForEach(personToBeDeleted => CurrentSession.Delete(personToBeDeleted));
CurrentSession.Flush();
}
}
}
}
请注意节省了多少代码,因为 PersonDao
只有一个已实现的方法,但具有几个自动继承的方法。
Person.hbm.xml 文件也很重要,下面将显示它:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="WebAppBasicNHibernate.Vo" assembly="WebAppBasicNHibernate">
<class name="Person" table="PERSON" >
<!-- Primary Key(s) -->
<id name="Id" column="ID">
<generator class="identity" />
</id>
<property name="Name" column="NAME" not-null="true" />
<property name="Age" column="AGE" not-null="true" />
</class>
</hibernate-mapping>
请注意将表列映射到对象属性。另请注意表定义。需要注意的一个重要细节是应用程序命名空间的使用。
设置好实体及其数据访问对象后,就可以进行一些数据库操作了。这将在下一节中讨论。
数据库交互示例
下载的应用程序包含一些 NHibernate 用法的示例。本节将演示它们。下面显示了 Global.asax 的完整代码。请注意,在 Application_Start
事件中,执行了一系列 NHibernate 数据库操作。创建了三个实体,删除了一个。此外,请注意使用默认的 Microsoft .NET 事务。这是允许的,并且使用此事务与使用 NHibernate 提供的事务之间没有区别。公平地说,NHibernate 事务有一个巨大的缺点:它不能嵌套在另一个 NHibernate 事务中。这会使事情变得复杂,因为当一个方法调用另一个方法时,必须小心检查它们是否都只使用一个 NHibernate 事务。
另一项重要声明:Application_Start
事件仅在应用程序启动时执行。要再次执行它,必须重新启动 Internet Information Services (IIS)。
using System;
using System.Collections.Generic;
using System.Transactions;
using log4net;
using log4net.Config;
using WebAppBasicNHibernate.Dao;
using WebAppBasicNHibernate.NHibernate;
using WebAppBasicNHibernate.Vo;
namespace WebAppBasicNHibernate
{
public class Global : System.Web.HttpApplication
{
protected SessionHelper _sessionHelper = null;
private static ILog _log =
LogManager.GetLogger(Log4NetConstants.WEB_APP_BASIC_NHIBERNATE_LOGGER);
protected void Application_Start(object sender, EventArgs e)
{
// start log4net
XmlConfigurator.Configure();
try
{
_sessionHelper = new SessionHelper();
_sessionHelper.OpenSession();
using (TransactionScope transactionScope = new TransactionScope())
{
PersonDao personDao = new PersonDao();
// delete all people, in case there are any
IList<Person> people = personDao.LoadAll();
if (people != null && people.Count > 0)
{
foreach (Person person in people)
{
personDao.Delete(person);
}
}
// create three people
Person jose = new Person();
jose.Name = "Jose";
jose.Age = 28;
personDao.SaveOrUpdate(jose);
Person maria = new Person();
maria.Name = "Maria";
maria.Age = 29;
personDao.SaveOrUpdate(maria);
Person mario = new Person();
mario.Name = "Mario";
mario.Age = 27;
personDao.SaveOrUpdate(mario);
// delete Mario
personDao.Delete(mario);
transactionScope.Complete();
}
_sessionHelper.CloseSession();
}
catch (Exception ex)
{
_log.Error("An error has occurred while initializing the application.", ex);
}
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
_sessionHelper = new SessionHelper();
_sessionHelper.OpenSession();
}
protected void Application_EndRequest(object sender, EventArgs e)
{
_sessionHelper = new SessionHelper();
_sessionHelper.CloseSession();
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
在 Default.aspx.cs 中可以看到另一个示例。这里执行了更多的 NHibernate 数据库操作。请注意使用了 NHibernate 事务。请记住,对于这种事务,不能有嵌套的异常。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WebAppBasicNHibernate.Vo;
using WebAppBasicNHibernate.Dao;
using log4net;
using NHibernate;
using WebAppBasicNHibernate.NHibernate;
namespace WebAppBasicNHibernate
{
public partial class Default : System.Web.UI.Page
{
private static ILog _log =
LogManager.GetLogger(Log4NetConstants.WEB_APP_BASIC_NHIBERNATE_LOGGER);
protected void Page_Load(object sender, EventArgs e)
{
}
private void ManipulatePerson()
{
try
{
SessionHelper sessionHelper = new SessionHelper();
using (ITransaction transaction = sessionHelper.Current.BeginTransaction())
{
PersonDao personDao = new PersonDao();
// remove John and Mary
personDao.DeleteByName("John");
personDao.DeleteByName("Mary");
_log.Info("Removed John and Mary, in case they do exist");
lblOperations.Text = "Removed John and Mary, in case they do exist";
// create john
Person john = new Person();
john.Name = "John";
john.Age = 32;
personDao.SaveOrUpdate(john);
_log.Info("Created John.");
lblOperations.Text += "<br>Created John.";
// create mary
Person mary = new Person();
mary.Name = "Mary";
mary.Age = 33;
personDao.SaveOrUpdate(mary);
_log.Info("Created Mary.");
lblOperations.Text += "<br>Created Mary.";
transaction.Commit();
}
}
catch (Exception ex)
{
// log exception in case any errors occur
_log.Error("Error while manipulating entities using NHibernate.", ex);
}
}
protected void btnExecuteNHibernateOperations_Click(object sender, EventArgs e)
{
// execute operations with NHibernate
ManipulatePerson();
}
}
}
这结束了代码解释。请不要忘记创建数据库以运行此应用程序。配置如前所述,在 Web.Config 文件中设置。
运行代码
项目编译和执行非常简单:
- 使用 Microsoft Visual Web Developer 2010 或更高版本打开项目。当然,您也可以使用 Visual Studio。
- 编译项目。请注意,第一次时,所有必需的库都将通过 NuGet 自动下载。
- 运行项目。
当项目运行时,数据库表将被创建,并且 Global.asax 中的操作仅在软件启动时执行。如前所述,只有当您重新启动 Internet Information Services (IIS) 时,它们才会再次执行。如果应用程序成功执行,将出现一个屏幕,如下所示:
如果您按下 ªExecute NHibernate Operationsª,将执行一些 NHibernate 数据库操作。这些操作已在上一节中讨论过。您可以看到结果已持久化到数据库中。
讨论
尽管本文内容广泛,但请注意,设置 NHibernate 并不复杂。基本上,需要导入所需的库,设置基本 Session
类,配置数据库,然后开始实现值对象和数据访问对象类。
NHibernate 是一个强大的框架,被 Microsoft .NET 开发者广泛使用,并且在 Java 用户中更加普及,当然是利用 Hibernate 框架。
NHibernate 之所以如此出名,是因为它节省了大量的编码时间。主要是因为它自动地将数据库数据转换为软件对象,反之亦然。它还允许开发人员在代码中构建复杂的查询,这极大地简化了软件开发和维护。
作为一个负面因素,NHibernate 的学习曲线相当陡峭,使其学习并非易事。然而,由于开发人员喜欢挑战,掌握这个框架是值得的。
Microsoft 发布了 Entity Framework,恕我直言,它是 NHibernate 的复制品,并带有可视化建模向导。即便如此,Entity Framework 的早期版本仍有很大的改进空间,这证明了构建这样一个框架的难度,以及 NHibernate 的成熟度。
通过 QueryOver API,NHibernate 仍然比 Entity Framework 更易于使用,并且即使到目前为止,在与 Microsoft SQL Server 以外的其他数据库一起使用时,它也更可靠。
总而言之,NHibernate 是一个伟大的框架,希望它能继续存在很多年。