本文将开始一步一步地使用Asp.net MVC 2 + Castle + NHibernate 开发一个项目。
在开始之前,我先对这三个组件做一个简单的介绍:
Asp.net MVC
它是微软提供的一个基于MVC标准的Web开发模式,其典型特点是有控制器和视图;在这之前,.NET下的Web开发模式大多是采用WebForm,其典型特点是服务端控件和后台触发事件;
NHibernate
它是一个ORM框架,使用Java的SSH做过项目开发的人就非常熟悉了,当前最新版本为NHibernate 3.0,听说完全支持Linq查询语句了,以前只支持HQL语句。
Castle
它是一个非常大的框架,包含IoC、MVC、ORM、AOP等,这次我只用到其IoC的功能。
关于IoC
IoC的英文是Inversion of Control,中文意思是控制反转,也有称其为Dependence Injection,中文意思是依赖注入,也就是DI;
除了Castle可以作IoC 外,还有著名的Spring.Net、Unity等,在我另外一个开源博客项目 http://rorowo.codeplex.com/ 中就用到了微软的Unity 2.0作为IoC。
好了,废话不多说,下面开始。
首先,第一步是创建一个解决方案,项目结构如下:
需要引用的DLL库文件,我们全部放在RoRoWo.Common.DependLib下:
根据表的结构,如图:
现在我们开始为表结构创建实体类,以BlogCategory表为例,我们根据该表的字段名称和数据类型创建一个POCO类,放在RoRoWo.Domain.Entities下,代码内容如下:
代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
namespace
RoRoWo.Domain {
public
class
Blogcategory {
public
Blogcategory() { }
public
virtual
int
Cateid {
get
;
set
; }
public
virtual
IList
<
Blogarticle
>
Blogarticles {
get
;
set
; }
public
virtual
string
Catename {
get
;
set
; }
public
virtual
int
Parentid {
get
;
set
; }
public
virtual
int
State {
get
;
set
; }
public
virtual
int
Sortid {
get
;
set
; }
public
virtual
int
Articlecount {
get
;
set
; }
public
virtual
System.DateTime Createtime {
get
;
set
; }
public
virtual
string
Note {
get
;
set
; }
}
}
在这里,我推荐一个可以生成NHibernate映射对象代码的工具(开源的),项目地址:NHibernate Mapping Generator(它同时支持 hbm.xml文件的方式、Fluent Mapping方式、Castle ActiveRecord方式)
接下来,要为这个类创建一个映射关系,我这里使用配置文件的方式,但是正式项目推荐使用Fluent方式。我们创建一个XML文件,文件名为“Blogcategory.hbm.xml”,放在RoRoWo.Domain.Mappings下,内容如下:
代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
hibernate
-
mapping assembly
=
"
RoRoWo.Domain
"
namespace
=
"
RoRoWo.Domain
"
xmlns
=
"
urn:nhibernate-mapping-2.2
"
default
-
lazy
=
"
false
"
>
<
class
name
=
"
Blogcategory
"
table
=
"
BlogCategory
"
>
<
id name
=
"
Cateid
"
column
=
"
CateID
"
>
<
generator
class
=
"
native
"
/>
</
id
>
<
property name
=
"
Catename
"
column
=
"
CateName
"
/>
<
property name
=
"
Parentid
"
column
=
"
ParentID
"
/>
<
property name
=
"
State
"
column
=
"
State
"
/>
<
property name
=
"
Sortid
"
column
=
"
SortID
"
/>
<
property name
=
"
Articlecount
"
column
=
"
ArticleCount
"
/>
<
property name
=
"
Createtime
"
column
=
"
CreateTime
"
/>
<
property name
=
"
Note
"
column
=
"
Note
"
/>
</
class
>
</
hibernate
-
mapping
>
这里就是一个典型的映射关系了,如果有一对多,多对多的表关系,也是在这个配置中进行维护。
创建这个XML后,还有个很重要的操作,就是将其设为“嵌入的资源” ,鼠标右键查看“Blogcategory.hbm.xml”文件属性,将“生成操作”项的“内容”改为“嵌入的资源”,如图:
到此,一个映射关系的实体就建立好了,下面我们就要来实现NHibernate对该表的增删改查操作了,我们把这些操作的实现放在RoRoWo.Data中。
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
注意,RoRoWo.Data需要添加对 “Castle.Core.dll”
"
Castle.DynamicProxy2.dll
"
"
NHibernate.dll
"
"
RoRoWo.Domain
"
的引用。
在创建数据库操作类之前,我们需要创建一个 “SessionManager”类,它负责维护整个ORM中的上下文,这里我使用李永京的一个类,其代码如下:
代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
NHibernate;
using
NHibernate.Cfg;
namespace
RoRoWo.Data
{
public
class
SessionManager
{
private
ISessionFactory _sessionFactory;
public
SessionManager()
{
_sessionFactory
=
GetSessionFactory();
}
private
ISessionFactory GetSessionFactory()
{
return
(
new
Configuration()).Configure().BuildSessionFactory();
}
public
ISession GetSession()
{
return
_sessionFactory.OpenSession();
}
}
}
我们创建一个“BlogCategoryRespository.cs”文件,其代码如下:
代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
NHibernate;
using
NHibernate.Cfg;
using
NHibernate.Criterion;
using
RoRoWo.Domain;
namespace
RoRoWo.Data
{
public
class
BlogCategoryRespository
{
private
ISession _session;
public
ISession Session
{
set
{
_session
=
value;
}
}
public
BlogCategoryRespository(ISession session)
{
_session
=
session;
}
public
Blogcategory GetById(
int
cateId)
{
return
_session.Get
<
Blogcategory
>
(cateId);
}
public
void
Create(Blogcategory dto)
{
_session.Save(dto);
_session.Flush();
}
public
int
CreateAndReturn(Blogcategory dto)
{
int
newid
=
(
int
)_session.Save(dto);
_session.Flush();
return
newid;
}
///
<summary>
///
使用事务
///
</summary>
///
<param name="dto"></param>
///
<returns></returns>
public
int
CreateTransaction(Blogcategory dto)
{
using
(ITransaction tx
=
_session.BeginTransaction())
{
try
{
int
newId
=
(
int
)_session.Save(dto);
_session.Flush();
tx.Commit();
return
newId;
}
catch
(HibernateException)
{
tx.Rollback();
throw
;
}
}
}
public
void
UpdateCustomer(Blogcategory dto)
{
_session.Update(dto);
_session.Flush();
}
public
void
SaveOrUpdate(IList
<
Blogcategory
>
dtos)
{
foreach
(var c
in
dtos)
{
_session.SaveOrUpdate(c);
}
_session.Flush();
}
public
void
Delete(Blogcategory dto)
{
_session.Delete(dto);
_session.Flush();
}
public
IList
<
Blogcategory
>
From()
{
//
返回所有Blogcategory类的实例
return
_session.CreateQuery(
"
from Blogcategory
"
)
.List
<
Blogcategory
>
();
}
public
IList
<
int
>
Select()
{
//
返回所有Blogcategory的CateId
return
_session.CreateQuery(
"
select c.CateId from Blogcategory c
"
)
.List
<
int
>
();
}
public
IList
<
Blogcategory
>
Where()
{
return
_session.CreateQuery(
"
from Blogcategory c where c.CateId='3'
"
)
.List
<
Blogcategory
>
();
}
public
IList
<
Blogcategory
>
GetGreaterThan(
int
CateId)
{
//
return _session.CreateQuery("select from Blogcategory c where c.CateId > :cid")
//
.SetInt32("cid", CateId)
//
.List<Blogcategory>();
return
_session.CreateCriteria(
typeof
(Blogcategory))
.Add(Restrictions.Gt(
"
CateId
"
, CateId))
.List
<
Blogcategory
>
();
}
public
IList
<
Blogcategory
>
CreateCriteria()
{
ICriteria crit
=
_session.CreateCriteria(
typeof
(Blogcategory));
crit.SetMaxResults(
50
);
IList
<
Blogcategory
>
blogcategorys
=
crit.List
<
Blogcategory
>
();
return
blogcategorys;
}
public
IList
<
Blogcategory
>
Narrowing()
{
IList
<
Blogcategory
>
blogcategorys
=
_session.CreateCriteria(
typeof
(Blogcategory))
.Add(Restrictions.Like(
"
Catename
"
,
"
s%
"
))
.Add(Restrictions.Between(
"
Parentid
"
,
"
1
"
,
"
3
"
))
.List
<
Blogcategory
>
();
return
blogcategorys;
}
public
IList
<
Blogcategory
>
Query()
{
Blogcategory dtoSample
=
new
Blogcategory() { Catename
=
"
sss
"
, Parentid
=
0
};
return
_session.CreateCriteria(
typeof
(Blogcategory))
.Add(Example.Create(dtoSample))
.List
<
Blogcategory
>
();
}
public
IList
<
Blogcategory
>
UseQueryByExample_Get(Blogcategory dtoSample)
{
Example example
=
Example.Create(dtoSample)
.IgnoreCase()
.EnableLike()
.SetEscapeCharacter(
'
&
'
);
return
_session.CreateCriteria(
typeof
(Blogcategory))
.Add(example)
.List
<
Blogcategory
>
();
}
}
}
该代码具有了对一个表的基本操作,现在我们就来创建一个单元测试,测试一下插入数据。
在创建插入操作时,我们要能使NHibernate正常工作,还需要创建一个配置文件,我们创建一个XML文件,文件名为“hibernate.cfg.xml”,放在RoRoWo.UnitTest下,其内容为:
代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
<?
xml version="1.0" encoding="utf-8"
?>
<
hibernate-configuration
xmlns
="urn:nhibernate-configuration-2.2"
>
<
session-factory
>
<
property
name
="connection.driver_class"
>
NHibernate.Driver.SqlClientDriver
</
property
>
<
property
name
="connection.connection_string"
>
Data Source=.;Initial Catalog=RoRoWoDB;User ID=sa;Password=2010;
</
property
>
<
property
name
="adonet.batch_size"
>
10
</
property
>
<
property
name
="show_sql"
>
true
</
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
>
<
property
name
="proxyfactory.factory_class"
>
NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle
</
property
>
<
mapping
assembly
="RoRoWo.Domain"
/>
</
session-factory
>
</
hibernate-configuration
>
其中“Data Source=.;Initial Catalog=RoRoWoDB;User ID=sa;Password=2010;”是我的数据库连接,您可以改为您的。
现在我们添加一个单元测试(不明白如何添加的请参考相关资料),先测试插入方法,其代码如下:
代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->
///
<summary>
///
Create 的测试
///
</summary>
[TestMethod()]
public
void
CreateTest()
{
SessionManager sessionManager
=
new
SessionManager();
ISession session
=
sessionManager.GetSession();
BlogCategoryRespository target
=
new
BlogCategoryRespository(session);
Blogcategory dto
=
new
Blogcategory();
dto.Catename
=
"
新分类
"
+
new
Random().Next(
100000
,
999999
).ToString();
dto.Parentid
=
0
;
dto.State
=
0
;
dto.Createtime
=
DateTime.Now;
int
newid
=
target.CreateAndReturn(dto);
Assert.IsTrue(newid
>
0
);
}
执行单元测试,可以通过测试,并且在数据库中已经成功插入了一条记录,结果完全正确;
我们接着对查询方法进行测试,我们将测试代码如下:
- 浏览: 20927 次
- 性别:
- 来自: 长沙
评论