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多层架构开发中的应用。
NHibernate 3.0在PetShop 3层架构中的应用
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">
</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">
</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.rar