在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
中的功能。 下面就有这个示例来看一下其具体的测试代码。首先下载并解压,并修改其中的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。
本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/163781,如需转载请自行联系原作者