NHibernate+WCF项目实战
第一篇、项目介绍与搭建;
第二篇、使用NHibernate实现数据访问并进行单元测试;
第三篇、使用WCF对外提供Webservices接口并进行单元测试;
第四篇、使用WAS对Webservices接口进行压力测试。
开发环境
我的开发环境是VS2008 SP1+SQLServer 2005
NHibernate版本是2.1.0.4000
NUnit版本是2.5.2
Microsoft Web Application Stress Tool 版本是1.1
本节概要
上一篇已经搭建了包含6个项目的解决方案,本节主要完成实体层和数据访问层的开发工作,同时使用NUnit对数据访问层中的方法进行单元测试。
准备工作
学习NHibernate
1)推荐系列文章:NHibernate之旅。
2)博客园也刚刚成立了NHibernate专题。
您可以先从sourceforge下载本项目需要的NHibernate程序集。下载以后Required_Bins下面是必须的程序集。Required_For_LazyLoading下面是延迟加载的三种方案所需的程序集。
开发Model
using
添加对NHibernate.dll的引用。
O/R Mapping
Model层主要是解决O/R Mapping。
R:我们在上一篇文章中已经建立了表UserInfo。
O:创建UserInfo对应的实体,UserInfo.cs。
using System;
using System.Collections.Generic;
namespace Lee.Model
{
/// <summary>
///
/// </summary>
[Serializable]
public class UserInfo
{
public UserInfo()
{
m_Id = 0;
m_Name = null;
m_Description = null;
m_State = null;
}
private int m_Id;
private string m_Name;
private string m_Description;
private string m_State;
///<summary>
///
///</summary>
public virtual int Id
{
get { return m_Id; }
set { m_Id = value; }
}
///<summary>
///
///</summary>
public virtual string Name
{
get { return m_Name; }
set { m_Name = value; }
}
///<summary>
///
///</summary>
public virtual string Description
{
get { return m_Description; }
set { m_Description = value; }
}
///<summary>
///
///</summary>
public virtual string State
{
get { return m_State; }
set { m_State = value; }
}
}
}
Mapping:创建映射文件UserInfo.hbm.xml,并设置为嵌入的资源和始终复制。
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Lee.Model.UserInfo, Lee.Model" table="UserInfo">
<id name="Id" column="id" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" type="String" column="name " />
<property name="Description" type="String" column="description " />
<property name="State" type="String" column="state " />
</class>
</hibernate-mapping>
开发DAL
using
添加对NHibernate.dll的引用。
添加对Lee.Model项目的引用。
创建NHibernate的Session辅助类,SessionFactory。
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
namespace Lee.DAL
{
public class SessionFactory
{
private static ISessionFactory _factory;
private static object obj = new object();
public ISession Session
{
get
{
if (_factory == null)
{
lock (obj)
{
if (_factory == null)
{
Configuration cfg = new Configuration().Configure();
_factory = cfg.BuildSessionFactory();
}
}
}
return _factory.OpenSession();
}
}
}
}
不知道NHibernate中Session怎么用的请系统学习我推荐地址的文章。我在这里就不做重复介绍了!
创建UserInfo的数据访问类UserInfoDAL
主要定义了三个方法:添加用户、修改用户信息和检查用户是否存在。
这三个方法也是WCF将要对外提供的用户操作方法,考虑到删除操作的特殊性,不对外提供删除接口。
下面是UserInfoDAL的代码:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lee.Model;
using NHibernate.Cfg;
using NHibernate;
namespace Lee.DAL
{
public class UserInfoDAL
{
private ISession _session;
private SessionFactory _sessionfactory = new SessionFactory();
/// <summary>
/// 添加用户
/// </summary>
/// <param name="name">用户名称</param>
/// <param name="description">用户描述</param>
/// <param name="state">状态</param>
/// <returns>True-操作成功|False-操作失败</returns>
public bool AddUserInfo(string name, string description,string state)
{
if (!ExistUserInfo(name))
{
UserInfo userinfo = new UserInfo
{
Name = name,
Description = description,
State = state
};
using (_session = _sessionfactory.Session)
{
_session.Save(userinfo);
_session.Flush();
}
return true;
}
else
{
return false;
}
}
/// <summary>
/// 检查用户是否存在
/// </summary>
/// <param name="name">用户名称</param>
/// <returns>True-用户存在|False-用户不存在</returns>
public bool ExistUserInfo(string name)
{
bool result = false;
string hql = "select count(*) from UserInfo where Name=:name";
using (_session = _sessionfactory.Session)
{
IQuery query = _session.CreateQuery(hql);
query.SetString("name", name);
result = (int.Parse(query.UniqueResult().ToString()) == 0) ? false : true;
}
return result;
}
/// <summary>
/// 更新用户信息
/// </summary>
/// <param name="name">用户名称</param>
/// <param name="description">用户描述</param>
/// <param name="state">状态</param>
/// <returns>True-操作成功|False-操作失败</returns>
public bool UpdateUserInfo(string name, string description, string state)
{
bool result = false;
if (ExistUserInfo(name))
{
string hql = "update UserInfo set Description=:description,State=:state where Name=:name";
using (_session = _sessionfactory.Session)
{
IQuery query = _session.CreateQuery(hql);
query.SetString("name", name);
query.SetString("description", description);
query.SetString("state", state);
result = (query.ExecuteUpdate() > 0) ? true : false;
}
}
else
{
result = false;
}
return result;
}
}
}
到这里我们已经完成了实体层和数据访问层的开发工作,下面我们用NUnit进行单元测试。
单元测试
安装NUnit
下载:http://www.nunit.org/index.php?p=download
using
添加对NHibernate.dll的引用。
添加对NHibernate.ByteCode.Castle的引用。
添加对nunit.framework的引用。
添加对Lee.Model项目的引用。
添加对Lee.DAL项目的引用。
copy以下程序集到\Lee.Test\bin\Debug下
NHibernate.dll
NHibernate.ByteCode.Castle.dll
Antlr3.Runtime.dll
Iesi.Collections.dll
log4net.dll
Castle.DynamicProxy2.dll
Castle.Core.dll
测试步骤
1)创建NHibernate配置文件hibernate.cfg.xml并设置为始终复制。
<hibernate-configuration xmlns='urn:nhibernate-configuration-2.2'>
<session-factory>
<property name="show_sql">true</property>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<property name="connection.connection_string_name">SQLConnection</property>
<mapping assembly="Lee.Model"/>
</session-factory>
</hibernate-configuration>
你需要自己配置以下节点:
数据库连接
<property name="connection.connection_string_name">SQLConnection</property>
mapping
<mapping assembly="Lee.Model"/>
2)创建应用程序配置文件App.config,设置数据库连接。
<configuration>
<connectionStrings>
<add name="SQLConnection" connectionString="Database=XX;User ID=sa;Password=saas;Server=XX;" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
3)创建测试类TestUserInfoDAL
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lee.Model;
using Lee.DAL;
using NUnit.Framework;
namespace Lee.Test
{
[TestFixture]
public class TestUserInfoDAL
{
[Test]
public void AddUserInfo()
{
UserInfoDAL dal = new UserInfoDAL();
bool result = dal.AddUserInfo("testname4", "testdesc", "teststate");
Assert.AreEqual(true, result);
}
[Test]
public void ExistUserInfo()
{
UserInfoDAL dal = new UserInfoDAL();
bool result = dal.ExistUserInfo("testname");
Assert.AreEqual(true, result);
}
[Test]
public void UpdateUserInfo()
{
UserInfoDAL dal = new UserInfoDAL();
bool result = dal.UpdateUserInfo("testname", "hello,testname!", "activation");
Assert.AreEqual(true, result);
}
}
}
4)设置项目 Lee.Test调试时启动NUnit。
5)设置该项目为启动项目,在测试方法中设置断点,项目启动后,会开启NUnit。
选择要测试的方法,Run即可单步调试程序了!
如果程序出现异常或者断言结果不相等(Assert.AreEqual)会出现红色进度条。 进度条下面有异常提示。
如果程序成功执行,当然就是一片绿了。