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,并设置为嵌入的资源和始终复制。
<?xml version="1.0" encoding="utf-8" ?>
<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;
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;
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并设置为始终复制。
<?xml version="1.0" encoding="utf-8" ?>
<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,设置数据库连接。
<?xml version="1.0" encoding="utf-8" ?>
<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;
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)会出现红色进度条。 进度条下面有异常提示。

如果程序成功执行,当然就是一片绿了。

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构