PetShop 及 NHibernate 对于.Net平台下的开发者一定很熟悉,前者是一个经典的软件开发架构,后者是是一个强大的ORM框架。
近期有一个项目,部分功能需要由原来的SQL Server数据改为Oracle数据,其中原来的DAL层用的是LINQ To SQL方式实现的,而微软LINQ并没有提供到Oracle的映射功能(在这里鄙视一下MS),如果要改成直接用ADO.NET来实现DAL层,无疑工作量是巨大的。通过综合考量决定使用其他ORM框架对项目进行改造,比较了一下常用的开源ORM框架,因为NHibernate最近推出了其3.0版本,里面集成了LINQ功能, 所以最后决定采用NHibernate对项目进行改造。
本文依据此次项目经历,整理出一个Demo,来体验一下NHibernate在基于PetShop多层架构开发中的应用。
一、资源准备
1、NHibernate下载
到http://sourceforge.net/projects/nhibernate/下载
NHibernate-3.0.0.Alpha2-bin
NHibernate-3.0.0.Alpha2-src
也可以点击此处下载NHibernate-3.0.0.Alpha2-bin
2、Demo开发环境
- Visual Studio 2008 (with sp1)
- SQL Server 2005
- Oracle 9i
二、开发环境配置
NHibernate支持VS环境下的智能提示,但得需要进行配置,方法如下:
1、解压缩NHibernate-3.0.0.Alpha2-bin.zip到当期目录
2、找到\NHibernate-3.0.0.Alpha2-bin\Required_Bins\目录中以下文件:
nhibernate-configuration.xsd
nhibernate-mapping.xsd
3、将以上两个文件Copy到以下目录:
C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas
三、数据结构设计
本例只设计了Oracle中表结构,SQL Server中的只需更改下数据类型。其实我们不必在数据库中直接创建表结构,因为NHibernate中提供了根据Model及映射文件自动创建表结构的功能,后面我们会陆续实现。
名称 |
Users |
说明 |
用户表 |
序号 |
字段名称 |
数据类型(长度) |
允许空 |
描述 |
备注说明 |
1 |
USER_ID |
VARCHAR2(32) |
|
|
PK |
2 |
USER_NAME |
VARCHAR2(50) |
|
|
|
3 |
PASSWORD |
VARCHAR2(32) |
|
|
|
4 |
|
|
|
|
|
5 |
|
|
|
|
|
主键 |
USER_ID |
名称 |
UserProfiles |
说明 |
用户Profile表 |
序号 |
字段名称 |
数据类型(长度) |
允许空 |
描述 |
备注说明 |
1 |
USER_ID |
VARCHAR(32) |
|
|
PK |
2 |
EMAIL |
VARCHAR(50) |
|
|
|
3 |
|
|
|
|
|
4 |
|
|
|
|
|
5 |
|
|
|
|
|
主键 |
USER_ID |
四、构建基于PetShop 4.0的三层程序架构
Demo中用到的各程序集如下图:
本文不对3层架构实现逻辑进行详解,后续会专门写一遍文章详细论述基于PetShop的3层软件架构。
五、构建持久化类
打开LXJ.NHibernate.Demo.Model程序集,创建目录Auth,在此目录下分别创建UserInfo.cs、UserProfileInfo.cs两个持久类,代码如下:
UserInfo.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
namespace
LXJ.NHibernate.Demo.Model.Auth
{
public
class
UserInfo
{
private
string
user_id;
private
string
user_name;
private
string
password;
public
virtual
string
USER_ID
{
get
{
return
this
.user_id; }
set
{
this
.user_id
=
value; }
}
public
virtual
string
USER_NAME
{
get
{
return
this
.user_name; }
set
{
this
.user_name
=
value; }
}
public
virtual
string
PASSWORD
{
get
{
return
this
.password; }
set
{
this
.password
=
value; }
}
}
//
}
//
UserProfileInfo.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
namespace
LXJ.NHibernate.Demo.Model.Auth
{
public
class
UserProfileInfo
{
private
string
user_id;
private
string
email;
public
virtual
string
USER_ID
{
get
{
return
this
.user_id; }
set
{
this
.user_id
=
value; }
}
public
virtual
string
EMAIL
{
get
{
return
this
.email; }
set
{
this
.email
=
value; }
}
}
}
六、编写映射文件
首先创建UserInfo.cs的映射文件,名称为“UserInfo.hbm.xml”,内容如下:
代码
<?
xml version="1.0" encoding="utf-8"
?>
<
hibernate-mapping
xmlns
="urn:nhibernate-mapping-2.2"
assembly
="LXJ.NHibernate.Demo.Model"
namespace
="LXJ.NHibernate.Demo.Model.Auth"
>
<
class
name
="LXJ.NHibernate.Demo.Model.Auth.UserInfo, LXJ.NHibernate.Demo.Model"
table
="Users"
>
<
id
name
="USER_ID"
column
="USER_ID"
type
="String"
length
="32"
>
<
generator
class
="assigned"
/>
</
id
>
<
property
name
="USER_NAME"
column
="USER_NAME"
type
="String"
length
="50"
not-null
="true"
/>
<
property
name
="PASSWORD"
column
="PASSWORD"
type
="String"
length
="32"
not-null
="true"
/>
</
class
>
</
hibernate-mapping
>
首先创建UserProfileInfo.cs的映射文件,名称为“UserProfileInfo.hbm.xml”,内容如下:
代码
<?
xml version="1.0" encoding="utf-8"
?>
<
hibernate-mapping
xmlns
="urn:nhibernate-mapping-2.2"
assembly
="LXJ.NHibernate.Demo.Model"
namespace
="LXJ.NHibernate.Demo.Model.Auth"
>
<
class
name
="LXJ.NHibernate.Demo.Model.Auth.UserProfileInfo, LXJ.NHibernate.Demo.Model"
table
="UserProfiles"
>
<
id
name
="USER_ID"
column
="USER_ID"
type
="String"
length
="32"
>
<
generator
class
="assigned"
/>
</
id
>
<
property
name
="EMAIL"
column
="EMAIL"
type
="String"
length
="50"
not-null
="true"
/>
</
class
>
</
hibernate-mapping
>
如果我们的第二步配置正确的话,映射文件中是支持智能提示的,但在配置映射文件时要注意下面的内容:
hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
一定要写对,某则不但智能提示没有,运行也会报错。
七、配置web.config
首先,在 <configSections>......</configSections>配置节点中增加以下代码:
<
section
name
="hibernate-configuration"
type
="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"
/>
然后,在 <configSections>......</configSections>配置节点外增加以下代码:
代码
<
hibernate-configuration
xmlns
="urn:nhibernate-configuration-2.2"
>
<
session-factory
name
="NHibernate.Test"
>
<
property
name
="connection.driver_class"
>
NHibernate.Driver.OracleClientDriver
</
property
>
<
property
name
="connection.connection_string"
>
Data Source=nhi;User id=xiaojun;Password=1qazxsw2;
</
property
>
<
property
name
="adonet.batch_size"
>
10
</
property
>
<
property
name
="show_sql"
>
false
</
property
>
<
property
name
="dialect"
>
NHibernate.Dialect.Oracle9iDialect
</
property
>
<
property
name
="use_outer_join"
>
true
</
property
>
<
property
name
="command_timeout"
>
10
</
property
>
<
property
name
="query.substitutions"
>
true 1, false 0, yes 'Y', no 'N'
</
property
>
<!--
2.1要配置延迟加载的代理 这里配置为Castle
-->
<
property
name
="proxyfactory.factory_class"
>
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</
property
>
<
mapping
assembly
="LXJ.NHibernate.Demo.Model"
/>
</
session-factory
>
</
hibernate-configuration
>
然后,在 <appSettings>.....</appSettings>配置节点增加如下代码:
代码
<
appSettings
>
<
add
key
="XmlConfigurationFilePath"
value
="C:\Users\Administrator\Desktop\cnblogs\NHibernate\Demo\Config\sqlserver.cfg.xml"
/>
<!--
映射DAL BEGIN
-->
<
add
key
="DAL"
value
="LXJ.NHibernate.Demo.NhiDAL"
/>
<
add
key
="SchemaDAL"
value
="LXJ.NHibernate.Demo.NhiDAL"
/>
<!--
映射DAL END
-->
</
appSettings
>
此段代码用于不依赖于web.config的配置,在下一步骤中会用到,这里先不讨论。其中以上配置节中的XmlConfigurationFilePath的值是一个xml文件的路径,本Demo中撰写了两个可配置的xml文件:oracle.cfg.xml、sqlserver.cfg.xml,分别用来演示不同数据库的映射,代码分别如下:
oracle.cfg.xml
代码
<?
xml version="1.0" encoding="utf-8"
?>
<!--
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it
for your own use before compile tests in VisualStudio.
-->
<!--
This is the System.Data.OracleClient.dll provider for Oracle from MS
-->
<
hibernate-configuration
xmlns
="urn:nhibernate-configuration-2.2"
>
<
session-factory
name
="NHibernate.Test"
>
<
property
name
="connection.driver_class"
>
NHibernate.Driver.OracleClientDriver
</
property
>
<
property
name
="connection.connection_string"
>
Data Source=nhi;User id=xiaojun;Password=1qazxsw2;
</
property
>
<
property
name
="adonet.batch_size"
>
10
</
property
>
<
property
name
="show_sql"
>
false
</
property
>
<
property
name
="dialect"
>
NHibernate.Dialect.Oracle9iDialect
</
property
>
<
property
name
="use_outer_join"
>
true
</
property
>
<
property
name
="command_timeout"
>
10
</
property
>
<
property
name
="query.substitutions"
>
true 1, false 0, yes 'Y', no 'N'
</
property
>
<!--
2.1要配置延迟加载的代理 这里配置为Castle
-->
<
property
name
="proxyfactory.factory_class"
>
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</
property
>
<
mapping
assembly
="LXJ.NHibernate.Demo.Model"
/>
</
session-factory
>
</
hibernate-configuration
>
sqlserver.cfg.xml
代码
<?
xml version="1.0" encoding="utf-8"
?>
<!--
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it
for your own use before compile tests in VisualStudio.
-->
<!--
This is the System.Data.OracleClient.dll provider for Oracle from MS
-->
<
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"
>
Data Source=liuxiaojun\sqlexpress;Initial Catalog=nhi;Persist Security Info=True;User ID=sa;Password=1qazxsw2
</
property
>
<
property
name
="adonet.batch_size"
>
10
</
property
>
<
property
name
="show_sql"
>
false
</
property
>
<
property
name
="dialect"
>
NHibernate.Dialect.MsSql2005Dialect
</
property
>
<
property
name
="use_outer_join"
>
true
</
property
>
<
property
name
="command_timeout"
>
10
</
property
>
<
property
name
="query.substitutions"
>
true 1, false 0, yes 'Y', no 'N'
</
property
>
<!--
2.1要配置延迟加载的代理 这里配置为Castle
-->
<
property
name
="proxyfactory.factory_class"
>
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</
property
>
<
mapping
assembly
="LXJ.NHibernate.Demo.Model"
/>
</
session-factory
>
</
hibernate-configuration
>
八、编写NHibernate帮助类
为了方便DAL层使用NHibernate,我们为其抽象出了一个帮助类,放到程序集“DBUtility”中,代码如下:
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.IO;
using NHibernate;
using NHibernate.Cfg;
namespace DBUtility
{
public abstract class NHibernateHelper
{
public static readonly string _XmlConfigFilePath = (System.Configuration.ConfigurationManager.AppSettings["XmlConfigurationFilePath"] == null) ? "" : System.Configuration.ConfigurationManager.AppSettings["XmlConfigurationFilePath"].ToString();
private static readonly bool _FromConfig = false;
public static readonly Configuration _Configuration;
private const string _CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory _SessionFactory;
[ThreadStatic]//声明为线程共享
public static ISession sessionWin;//winform程序使用
static NHibernateHelper()
{
log4net.Config.XmlConfigurator.Configure();
_Configuration = new Configuration();
//判断是否有单独的配置文件,如果有,则以配置文件为准;反之,以web.config为准
//注意:一定要为实际物理地址
if (!string.IsNullOrEmpty(_XmlConfigFilePath) && File.Exists(_XmlConfigFilePath))
{
//有
_SessionFactory = _Configuration.Configure(_XmlConfigFilePath).BuildSessionFactory();
_FromConfig = false;
}
else
{
//无
_SessionFactory = _Configuration.Configure().BuildSessionFactory();
_FromConfig = true;
}
}
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
if (context != null)
{
//webform程序使用
ISession currentSession = context.Items[_CurrentSessionKey] as ISession;
if (currentSession == null)
{
currentSession = _SessionFactory.OpenSession();
context.Items[_CurrentSessionKey] = currentSession;
}
else
{
if (!currentSession.IsConnected)
{
currentSession = _SessionFactory.OpenSession();
}
}
return currentSession;
}
else
{
//winform程序使用
if (sessionWin.Equals(null))
{
sessionWin = _SessionFactory.OpenSession();
}
return sessionWin;
}
}
public static ISession GetCurrentSession(string configFilePath)
{
//是否和默认配置文件一样
if ((_XmlConfigFilePath == configFilePath) || (_FromConfig))
{
return GetCurrentSession();
}
else
{
HttpContext context = HttpContext.Current;
if (context != null)
{
//webform程序使用
ISession currentSession = context.Items[configFilePath] as ISession;
if (currentSession == null)
{
currentSession = new Configuration().Configure(configFilePath).BuildSessionFactory().OpenSession();
context.Items[configFilePath] = currentSession;
}
else
{
if (!currentSession.IsConnected)
{
currentSession = _SessionFactory.OpenSession();
}
}
return currentSession;
}
else
{
//winform程序使用
if (sessionWin.Equals(null))
{
sessionWin = new Configuration().Configure(configFilePath).BuildSessionFactory().OpenSession();
}
return sessionWin;
}
}
}
public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[_CurrentSessionKey] as ISession;
if (currentSession == null)
{
// No current session
return;
}
currentSession.Close();
context.Items.Remove(_CurrentSessionKey);
}
public static void CloseSession(string configFilePath)
{
if ((_XmlConfigFilePath == configFilePath) || (_FromConfig))
{
CloseSession();
}
else
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[configFilePath] as ISession;
if (currentSession == null)
{
// No current session
return;
}
currentSession.Close();
context.Items.Remove(configFilePath);
}
}
public static void CloseSessionFactory()
{
if (_SessionFactory != null)
{
_SessionFactory.Close();
}
}
}//
}//
帮助类中的静态构造函数负责初始化配置信息,其中配置信息先读取
<
appSettings
>
<
add
key
="XmlConfigurationFilePath"
value
="C:\Users\Administrator\Desktop\cnblogs\NHibernate\Demo\Config\sqlserver.cfg.xml"
/>
</
appSettings
>
如果对应文件存在,则读取扩展的配置文件;否则读取web.config中的配置信息;
九、实现DAL层
在DAL层的程序集“LXJ.NHibernate.Demo.NhiDAL”下新增一个Auth文件夹,然后在Auth下增加一个类文件UserDAL.cs,代码继承程序集LXJ.NHibernate.Demo.IDAL下“Auth\IUser.cs”接口,完整代码如下:
LXJ.NHibernate.Demo.IDAL\Auth\IUser.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
LXJ.NHibernate.Demo.Model.Auth;
namespace
LXJ.NHibernate.Demo.IDAL.Auth
{
public
interface
IUser
{
bool
Exists(
string
user_id);
bool
Insert(UserInfo info);
bool
Update(UserInfo info);
void
Delete(
string
user_id);
UserInfo GetInfo(
string
user_id);
IList
<
UserInfo
>
GetList();
bool
Login(
string
user_id,
string
password);
}
}
LXJ.NHibernate.Demo.NhiDAL\Auth\UserDAL.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
NHibernate;
using
NHibernate.Linq;
using
LXJ.NHibernate.Demo.Model.Auth;
using
LXJ.NHibernate.Demo.IDAL.Auth;
using
DBUtility;
namespace
LXJ.NHibernate.Demo.NhiDAL.Auth
{
public
class
UserDAL : IUser
{
///
<summary>
///
判断是否存在
///
</summary>
///
<param name="user_id"></param>
///
<returns></returns>
public
bool
Exists(
string
user_id)
{
bool
result_stat
=
false
;
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
var user
=
session.Query
<
UserInfo
>
().SingleOrDefault(u
=>
u.USER_ID
==
user_id);
if
(user
!=
null
)
{
result_stat
=
true
;
}
}
return
result_stat;
}
///
<summary>
///
新增
///
</summary>
///
<param name="info"></param>
///
<returns></returns>
public
bool
Insert(UserInfo info)
{
bool
result_stat
=
false
;
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
UserInfo exists_user
=
session.Query
<
UserInfo
>
().SingleOrDefault(u
=>
u.USER_ID
==
info.USER_ID);
if
(exists_user
==
null
)
{
session.BeginTransaction();
session.Save(info);
session.Transaction.Commit();
result_stat
=
true
;
}
}
return
result_stat;
}
///
<summary>
///
更新
///
</summary>
///
<param name="info"></param>
///
<returns></returns>
public
bool
Update(UserInfo info)
{
bool
result_stat
=
false
;
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
UserInfo exists_user
=
session.Query
<
UserInfo
>
().SingleOrDefault(u
=>
u.USER_ID
==
info.USER_ID);
if
(exists_user
!=
null
)
{
exists_user.USER_NAME
=
info.USER_NAME;
session.BeginTransaction();
session.SaveOrUpdate(exists_user);
session.Transaction.Commit();
result_stat
=
true
;
}
}
return
result_stat;
}
///
<summary>
///
删除
///
</summary>
///
<param name="user_id"></param>
public
void
Delete(
string
user_id)
{
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
UserInfo exists_user
=
session.Query
<
UserInfo
>
().SingleOrDefault(u
=>
u.USER_ID
==
user_id);
if
(exists_user
!=
null
)
{
session.BeginTransaction();
session.Delete(exists_user);
session.Transaction.Commit();
}
}
}
///
<summary>
///
Get
///
</summary>
///
<param name="user_id"></param>
///
<returns></returns>
public
UserInfo GetInfo(
string
user_id)
{
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
UserInfo exists_user
=
session.Query
<
UserInfo
>
().SingleOrDefault(u
=>
u.USER_ID
==
user_id);
return
exists_user;
}
}
///
<summary>
///
GetList
///
</summary>
///
<returns></returns>
public
IList
<
UserInfo
>
GetList()
{
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
IList
<
UserInfo
>
users
=
session.Query
<
UserInfo
>
().ToList();
return
users;
}
}
///
<summary>
///
Login
///
</summary>
///
<param name="user_id"></param>
///
<param name="password"></param>
///
<returns></returns>
public
bool
Login(
string
user_id,
string
password)
{
bool
result_stat
=
false
;
using
(ISession session
=
NHibernateHelper.GetCurrentSession())
{
UserInfo exists_user
=
session.Query
<
UserInfo
>
().SingleOrDefault(u
=>
u.USER_ID
==
user_id
&&
u.PASSWORD
==
password);
if
(exists_user
==
null
)
{
result_stat
=
true
;
}
}
return
result_stat;
}
}
//
}
//
十、实现BLL层
BLL层采用工厂模式、反射机制、接口机制来实现对DAL层的访问,详细代码如下:
LXJ.NHibernate.Demo.BLL\Auth\UserManager.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
LXJ.NHibernate.Demo.Model.Auth;
using
LXJ.NHibernate.Demo.IDAL.Auth;
using
LXJ.NHibernate.Demo.DALFactory.Auth;
namespace
LXJ.NHibernate.Demo.BLL.Auth
{
public
class
UserManager
{
private
static
readonly
IUser dal
=
DataAccess.CreateUser();
public
static
bool
Exists(
string
user_id)
{
return
dal.Exists(user_id);
}
public
static
bool
Insert(UserInfo info)
{
return
dal.Insert(info);
}
public
static
bool
Update(UserInfo info)
{
return
dal.Update(info);
}
public
static
void
Delete(
string
user_id)
{
dal.Delete(user_id);
}
public
static
UserInfo GetInfo(
string
user_id)
{
return
dal.GetInfo(user_id);
}
public
static
IList
<
UserInfo
>
GetList()
{
return
dal.GetList();
}
public
static
bool
Login(
string
user_id,
string
password)
{
return
dal.Login(user_id, password);
}
}
//
}
//
LXJ.NHibernate.Demo.DALFactory\Auth\DataAccess.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
LXJ.NHibernate.Demo.Model.Auth;
using
LXJ.NHibernate.Demo.IDAL.Auth;
namespace
LXJ.NHibernate.Demo.DALFactory.Auth
{
public
class
DataAccess
{
private
static
readonly
string
path
=
"
Auth.
"
;
private
DataAccess() { }
///
<summary>
///
创建IUser对象实例
///
</summary>
///
<returns></returns>
public
static
IUser CreateUser()
{
return
(IUser)Utility.ReflectServiceLocator.LocateObject(
"
DAL
"
, path
+
"
UserDAL
"
);
}
}
}
十一、实现表示层
界面设计如图:
前台代码如下:
代码
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
ViewData.aspx.cs
"
Inherits
=
"
ViewData
"
%>
<!
DOCTYPE html PUBLIC
"
-//W3C//DTD XHTML 1.0 Transitional//EN
"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
"
>
<
html xmlns
=
"
http://www.w3.org/1999/xhtml
"
>
<
head runat
=
"
server
"
>
<
title
>
NHibernate Demo 之 Web Site
</
title
>
</
head
>
<
body
>
<
form id
=
"
form1
"
runat
=
"
server
"
>
<
div
>
<
a href
=
"
Default.aspx
"
>
[Back To Main]
</
a
>
</
div
>
<
div
>
<
fieldset
>
<
legend
>
Add User
</
legend
>
<
table border
=
"
1
"
width
=
"
600
"
cellpadding
=
"
4
"
cellspacing
=
"
0
"
>
<
tr
>
<
td width
=
"
100
"
align
=
"
right
"
>
USER ID
</
td
>
<
td
>
<
asp:TextBox ID
=
"
txtUSER_ID
"
runat
=
"
server
"
ValidationGroup
=
"
Add
"
Width
=
"
200px
"
></
asp:TextBox
>
<
asp:RequiredFieldValidator ID
=
"
RequiredFieldValidator1
"
runat
=
"
server
"
ControlToValidate
=
"
txtUSER_ID
"
ErrorMessage
=
"
Need User Id
"
SetFocusOnError
=
"
True
"
ValidationGroup
=
"
Add
"
>*</
asp:RequiredFieldValidator
>
</
td
>
</
tr
>
<
tr
>
<
td width
=
"
100
"
align
=
"
right
"
>
USER NAME
</
td
>
<
td
>
<
asp:TextBox ID
=
"
txtUSER_NAME
"
runat
=
"
server
"
ValidationGroup
=
"
Add
"
Width
=
"
200px
"
></
asp:TextBox
>
<
asp:RequiredFieldValidator ID
=
"
RequiredFieldValidator2
"
runat
=
"
server
"
ControlToValidate
=
"
txtUSER_NAME
"
ErrorMessage
=
"
Need User Name
"
SetFocusOnError
=
"
True
"
ValidationGroup
=
"
Add
"
>*</
asp:RequiredFieldValidator
>
</
td
>
</
tr
>
<
tr
>
<
td width
=
"
100
"
align
=
"
right
"
>
PASSOWORD
</
td
>
<
td
>
<
asp:TextBox ID
=
"
txtPASSWORD
"
runat
=
"
server
"
TextMode
=
"
Password
"
ValidationGroup
=
"
Add
"
Width
=
"
200px
"
></
asp:TextBox
>
<
asp:RequiredFieldValidator ID
=
"
RequiredFieldValidator3
"
runat
=
"
server
"
ControlToValidate
=
"
txtPASSWORD
"
ErrorMessage
=
"
Need Passord
"
SetFocusOnError
=
"
True
"
ValidationGroup
=
"
Add
"
>*</
asp:RequiredFieldValidator
>
</
td
>
</
tr
>
<
tr
>
<
td width
=
"
100
"
align
=
"
right
"
>
&
nbsp;
</
td
>
<
td
>
<
asp:Button ID
=
"
btnAdd
"
runat
=
"
server
"
OnClick
=
"
btnAdd_Click
"
Text
=
"
Add
"
ValidationGroup
=
"
Add
"
/>
<
asp:ValidationSummary ID
=
"
ValidationSummary1
"
runat
=
"
server
"
ShowMessageBox
=
"
True
"
ShowSummary
=
"
False
"
ValidationGroup
=
"
Add
"
/>
</
td
>
</
tr
>
<
tr
>
<
td width
=
"
100
"
align
=
"
right
"
>
&
nbsp;
</
td
>
<
td
>
<
asp:Label ID
=
"
labelMSG
"
runat
=
"
server
"
ForeColor
=
"
Red
"
></
asp:Label
>
</
td
>
</
tr
>
</
table
>
</
fieldset
>
<
br
/>
<
fieldset
>
<
legend
>
List User
</
legend
>
<
table border
=
"
1
"
width
=
"
600
"
cellpadding
=
"
1
"
cellspacing
=
"
0
"
>
<
tr
>
<
td align
=
"
center
"
>
<
asp:GridView ID
=
"
GridView1
"
runat
=
"
server
"
AutoGenerateColumns
=
"
False
"
Width
=
"
100%
"
onrowcancelingedit
=
"
GridView1_RowCancelingEdit
"
onrowdeleting
=
"
GridView1_RowDeleting
"
onrowediting
=
"
GridView1_RowEditing
"
onrowupdating
=
"
GridView1_RowUpdating
"
>
<
Columns
>
<
asp:BoundField DataField
=
"
USER_ID
"
HeaderText
=
"
USER_ID
"
ReadOnly
=
"
True
"
/>
<
asp:TemplateField HeaderText
=
"
USER_NAME
"
>
<
EditItemTemplate
>
<
asp:TextBox ID
=
"
txtROW_USER_NAME
"
runat
=
"
server
"
Text
=
'
<%# Bind("USER_NAME") %>
'
></
asp:TextBox
>
</
EditItemTemplate
>
<
ItemTemplate
>
<
asp:Label ID
=
"
Label1
"
runat
=
"
server
"
Text
=
'
<%# Bind("USER_NAME") %>
'
></
asp:Label
>
</
ItemTemplate
>
</
asp:TemplateField
>
<
asp:CommandField ShowEditButton
=
"
True
"
/>
<
asp:CommandField ShowDeleteButton
=
"
True
"
/>
</
Columns
>
</
asp:GridView
>
</
td
>
</
tr
>
</
table
>
</
fieldset
>
</
div
>
</
form
>
</
body
>
</
html
>
后台代码如下:
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
LXJ.NHibernate.Demo.Model.Auth;
public
partial
class
ViewData : System.Web.UI.Page
{
protected
void
Page_Load(
object
sender, EventArgs e)
{
if
(
!
Page.IsPostBack)
{
this
.GetList();
}
}
private
void
GetList()
{
this
.GridView1.DataSource
=
LXJ.NHibernate.Demo.BLL.Auth.UserManager.GetList();
this
.GridView1.DataBind();
}
protected
void
btnAdd_Click(
object
sender, EventArgs e)
{
string
user_id
=
this
.txtUSER_ID.Text;
string
user_name
=
this
.txtUSER_NAME.Text;
string
password
=
this
.txtPASSWORD.Text;
if
(LXJ.NHibernate.Demo.BLL.Auth.UserManager.Exists(user_id))
{
this
.labelMSG.Text
=
"
存在此USER_ID:
"
+
user_id;
}
else
{
UserInfo user
=
new
UserInfo();
user.USER_ID
=
user_id;
user.USER_NAME
=
user_name;
user.PASSWORD
=
password;
if
(LXJ.NHibernate.Demo.BLL.Auth.UserManager.Insert(user))
{
labelMSG.Text
=
"
新增成功
"
;
this
.txtUSER_ID.Text
=
""
;
this
.txtUSER_NAME.Text
=
""
;
this
.txtPASSWORD.Text
=
""
;
this
.GetList();
}
else
{
labelMSG.Text
=
"
新增失败
"
;
}
}
}
protected
void
GridView1_RowEditing(
object
sender, GridViewEditEventArgs e)
{
this
.GridView1.EditIndex
=
e.NewEditIndex;
this
.GetList();
}
protected
void
GridView1_RowUpdating(
object
sender, GridViewUpdateEventArgs e)
{
string
user_id
=
this
.GridView1.Rows[e.RowIndex].Cells[
0
].Text;
string
user_name
=
((TextBox)
this
.GridView1.Rows[e.RowIndex].Cells[
1
].FindControl(
"
txtROW_USER_NAME
"
)).Text;
UserInfo user
=
new
UserInfo();
user.USER_ID
=
user_id;
user.USER_NAME
=
user_name;
if
(LXJ.NHibernate.Demo.BLL.Auth.UserManager.Update(user))
{
labelMSG.Text
=
"
更新成功
"
;
this
.GridView1.EditIndex
=
-
1
;
this
.GetList();
}
else
{
labelMSG.Text
=
"
更新失败
"
;
}
}
protected
void
GridView1_RowCancelingEdit(
object
sender, GridViewCancelEditEventArgs e)
{
this
.GridView1.EditIndex
=
-
1
;
this
.GetList();
}
protected
void
GridView1_RowDeleting(
object
sender, GridViewDeleteEventArgs e)
{
string
user_id
=
this
.GridView1.Rows[e.RowIndex].Cells[
0
].Text;
LXJ.NHibernate.Demo.BLL.Auth.UserManager.Delete(user_id);
this
.GetList();
labelMSG.Text
=
""
;
}
}
十二、自动创建Schema
NHibernate根据Model类定义及映射文件配置,可以在目标数据库中自动生成对应表结构,具体实现细节参照以下代码:
LXJ.NHibernate.Demo.NhiDAL\Auth\SchemaDAL.cs
代码
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
NHibernate;
using
NHibernate.Linq;
using
NHibernate.Tool.hbm2ddl;
using
LXJ.NHibernate.Demo.IDAL;
using
LXJ.NHibernate.Demo.Model.Auth;
using
DBUtility;
namespace
LXJ.NHibernate.Demo.NhiDAL
{
public
class
SchemaDAL : ISchema
{
public
bool
Create()
{
bool
result_stat
=
false
;
try
{
SchemaExport export
=
new
SchemaExport(NHibernateHelper._Configuration);
export.Create(
false
,
true
);
ISession session
=
NHibernateHelper.GetCurrentSession();
session.BeginTransaction();
UserInfo user1
=
new
UserInfo();
user1.USER_ID
=
"
User1
"
;
user1.USER_NAME
=
"
User Name 1
"
;
user1.PASSWORD
=
"
1234
"
;
session.Save(user1);
UserInfo user2
=
new
UserInfo();
user2.USER_ID
=
"
User2
"
;
user2.USER_NAME
=
"
User Name 2
"
;
user2.PASSWORD
=
"
1234
"
;
session.Save(user2);
session.Transaction.Commit();
result_stat
=
true
;
}
catch
{
throw
;
}
return
result_stat;
}
public
bool
Drop()
{
bool
result_stat
=
false
;
try
{
SchemaExport export
=
new
SchemaExport(NHibernateHelper._Configuration);
export.Drop(
false
,
true
);
result_stat
=
true
;
}
catch
{
}
return
result_stat;
}
}//
}//
这里只写出了DAL层的实现代码,其上各层代码请参照Demo的源程序。
源程序下载: LXJ.NHibernate.Demo.rarc
来源:http://www.cnblogs.com/liuxiaojun/articles/example_nhibernate_in_petshop.html