在Suteki.Shop中内置了提供了基于NHibernate方式的ORM功能,只不过就目前的项目进度还未全
部完成其设计时的构想,另外在单元测试上也没有完整的测试。不过其设计思路还是很有意思的。
就其将NHibernate引入到项目中的实现方式而言,与Rhino.Commons中所提倡的方式如出一辙,那
就是基于IRepository模式。关于IRepository这个接口的定义在之前的这篇文章中已提到并做了相应说
明,所以这里就不多做解释了。
好了,下面就开始今天的正文。
首先让我们看一下这个类图:
左侧的类NHibernateRepository就是基于IRepository 基本的具体实现,也就是所谓的CRUD操作。
下面就是其具体实现代码:
public
class
NHibernateRepository
<
T
>
: IRepository
<
T
>
, IRepository
where
T :
class
{
private
readonly
ISessionManager sessionManager;
public
NHibernateRepository(ISessionManager sessionManager)
{
this
.sessionManager
=
sessionManager;
}
private
ISession Session
{
get
{
return
sessionManager.OpenSession();
}
}
public
T GetById(
int
id)
{
return
Session.Load
<
T
>
(id);
}
public
IQueryable
<
T
>
GetAll()
{
return
Session.Linq
<
T
>
();
}
public
void
InsertOnSubmit(T entity)
{
Session.Save(entity);
}
public
void
DeleteOnSubmit(T entity)
{
Session.Delete(entity);
}
public
void
SubmitChanges()
{
Session.Flush();
}
object
IRepository.GetById(
int
id)
{
return
GetById(id);
}
IQueryable IRepository.GetAll()
{
return
GetAll();
}
void
IRepository.InsertOnSubmit(
object
entity)
{
InsertOnSubmit((T)entity);
}
void
IRepository.DeleteOnSubmit(
object
entity)
{
DeleteOnSubmit((T)entity);
}
}
该类的构造方法中接收ISessionManager实例做为其会话管理器。在castle中提供了"NHibernateIntegration"
对NHibernate进行了集成,对Session和Transaction进行了封装。所以这里可以使用该ISessionManager对Model中
的数据对象进行所谓的CRUD操作。因为这里还使用了NHibernate.Linq.dll,以此来替代Linq to Sql,所以其余的
代码比较与Linq有些相似,这里就不多做说明了。
下面再看一下NHibernateEntityTypeResolver(Suteki.Common\Services\NHibernateEntityTypeResolver.cs),
其功能就是将指定的Model中的指定实体类映影成NHibernate中的Entity,下面是其具体实现:
public
class
NHibernateEntityTypeResolver : IEntityTypeResolver
{
public
Type GetTypeOf(IEntity entity)
{
return
NHibernateProxyHelper.GuessClass(entity);
}
public
Type GetRealTypeOf(Type type)
{
var nhibernateProxyInterface
=
type.GetInterface(
"
INHibernateProxy
"
);
if
(nhibernateProxyInterface
==
null
)
{
return
type;
}
return
type.BaseType;
}
}
有了这两个类就可以在项目中使用它们了。只不过目前Suteki.Shop还未实现NHibernate方式的ORM,所以
还未进行单元测试。不过作者在其BLOG中还是在这篇文章中提供了一个示例,来测试运行NHibernateRepository
中的功能。
下面就有这个示例来看一下其具体的测试代码。首先下载并解压该示例的ZIP文件,并修改其中的config文件
"Keith.WindsorHNibernate.Tests.dll.Windsor.config",找出里面的数据连接串,替换成为我们本地的数据库
链接。
下面我们就看一下其中的测试代码:
[TestFixture]
public
class
RepositoryTests : WindsorNHibernateContainerTest
{
private
IRepository
<
Customer
>
customerRepository;
[SetUp]
public
void
SetUp()
{
customerRepository
=
GetComponet
<
IRepository
<
Customer
>>
();
}
[Test]
public
void
Customer_RepositoryShouldNotBeNull()
{
var customers
=
customerRepository.GetAll();
foreach
(var customer
in
customers)
{
Console.WriteLine(
"
Customer: {0}
"
, customer.ContactName);
foreach
(var order
in
customer.Orders)
{
Console.WriteLine(
"
\tOrder: {0}
"
, order.OrderID);
}
}
Assert.That(customers, Is.Not.Null);
}
这个示例中链接的数据库为Northwind,而这个单元测试就是获取数据库中的所有“客户信息”。
注意,其中customerRepository为IRepository<Customer>类型,其最终绑定的类型就是上面所定义
的NHibernateRepository(通过IOC绑定实现)。
相信Suteki.Shop会在将来完善这方面的代码,最终给用户提供至少两种数据访问方案:
一种是Linq To Sql,一种是 NHibernate。
好了,今天的内容就到这里了。
作者: daizhj,代震军,LaoD
Tags: mvc,Suteki.Shop,NHibernate
网址: http://daizhj.cnblogs.com/