`

Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

阅读更多

本文将开始一步一步地使用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 { getset; }
        
public virtual IList<Blogarticle> Blogarticles { getset; }
        
public virtual string Catename { getset; }
        
public virtual int Parentid { getset; }
        
public virtual int State { getset; }
        
public virtual int Sortid { getset; }
        
public virtual int Articlecount { getset; }
        
public virtual System.DateTime Createtime { getset; }
        
public virtual string Note { getset; }
    }
}

 

 在这里,我推荐一个可以生成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(100000999999).ToString();
            dto.Parentid = 0;
            dto.State = 0;
            dto.Createtime = DateTime.Now;

            
int newid = target.CreateAndReturn(dto);
            Assert.IsTrue(newid > 0);
        }

 

 执行单元测试,可以通过测试,并且在数据库中已经成功插入了一条记录,结果完全正确;

我们接着对查询方法进行测试,我们将测试代码如下:

代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->        /// <summary>
        
///GetById 的测试
        
///</summary>
        [TestMethod()]
        
public void GetByIdTest()
        {
            SessionManager sessionManager = new SessionManager();
            ISession session = sessionManager.GetSession();
            BlogCategoryRespository target = new BlogCategoryRespository(session);
            
int cateId = 3;
            Blogcategory actual;
            actual = target.GetById(cateId);
            Assert.AreEqual(cateId, actual.Cateid);

        }

        
/// <summary>
        
///From 的测试
        
///</summary>
        [TestMethod()]
        
public void FromTest()
        {
            SessionManager sessionManager = new SessionManager();
            ISession session = sessionManager.GetSession();
            BlogCategoryRespository target = new BlogCategoryRespository(session);
            IList<Blogcategory> actual;
            actual = target.From();
            Assert.IsTrue(actual.Count > 0);

        }

        
/// <summary>
        
///Select 的测试
        
///</summary>
        [TestMethod()]
        
public void SelectTest()
        {
            SessionManager sessionManager = new SessionManager();
            ISession session = sessionManager.GetSession();
            BlogCategoryRespository target = new BlogCategoryRespository(session);
            IList<int> actual;
            actual = target.Select();
            Assert.IsTrue(actual.Count > 0);
        }

        
/// <summary>
        
///Where 的测试
        
///</summary>
        [TestMethod()]
        
public void WhereTest()
        {
            SessionManager sessionManager = new SessionManager();
            ISession session = sessionManager.GetSession();
            BlogCategoryRespository target = new BlogCategoryRespository(session);

            IList<Blogcategory> actual;
            actual = target.Where();
            Assert.IsTrue(actual.C
分享到:
评论

相关推荐

    asp.net mvc2

    ASP.NET MVC2是微软开发的一款基于模型-视图-控制器(Model-View-Controller)设计模式的Web应用程序框架。这个框架允许开发者通过分离关注点来构建可维护性和可测试性的应用,提供了对HTTP请求处理的强大控制,以及...

    Test-Drive ASP.NET MVC

    Throughout, you’ll work with open source projects that complement ASP.NET MVC, including NHibernate, MVCContrib, and Castle Windsor Container. These tools speed up developing database components, ...

    NHibernate ASP.NET 2.0 企业级应用案例 1/3

    - **MonoRail**:Castle Project提供的MVC框架,为ASP.NET应用提供了另一种轻量级且功能强大的选择。 - **ActiveRecord**:同样来自Castle Project,提供了一种简单而强大的ORM解决方案,适用于那些寻求快速原型开发...

    23个.NET开源项目

    此外,文中还特别提到了一些遵循MS-PL(Microsoft Public License)许可的开源项目,如ASP.NET MVC、.NET Dynamic Language Runtime (DLR)、IronRuby、IronPython、Silverlight Toolkit、Ajax Control Toolkit、...

    ASP.NET设计模式-杨明军译(源码)

    8.4.2 ASP.NET MVC框架 8.4.3 利用AutoMapper映射ViewModel 8.4.4 Castle MonoRail 8.5 Page Controller模式 8.6 小结 第9章 用户体验层 9.1 什么是AJAX 9.2 使用JavaScript库 9.3 理解AJAX模式 9.3.1 ...

    Castle框架

    1. **MVC应用开发**: Castle框架可以很好地与ASP.NET MVC集成,通过Windsor容器管理控制器和服务,实现依赖注入,提高代码的可测试性和可维护性。 2. **微服务架构**: 由于其轻量级的特性,Castle框架适合构建微...

    Castle-2.5源码

    Castle项目是一个开源.NET框架,它提供了一系列强大的工具和库,如依赖注入容器、动态代理、以及ASP.NET MVC的实现等。本文将聚焦于 Castle-2.5 版本的源码,探讨其中的关键技术和设计理念。 一、依赖注入(DI)与...

    OrchardCH基于net框架的开源CMS

    综上所述,Orchard CMS是一个功能完备且高度可定制的.NET CMS平台,它结合了ASP.NET MVC的灵活性、NHibernate的数据管理、Autofac的服务定位以及 Castle Windsor的额外支持,为开发者提供了一个高效、强大的Web开发...

    VS.NET开源框架

    1. Castle Castle 是一个 .NET 系统级框架,它通过将一些成熟开源应用进行无缝整合而成的一套完善的应用系统框架。它的核心实现是 MicroKernel/Windsor,它采用 IoC 容器对系统进行运行期动态设置,主要包括 ...

    Castle 源码 源代码

    3. **Castle MonoRail**:这是一款Web应用框架,与ASP.NET MVC类似,但更注重于MVC模式的实现。MonoRail强调控制器的职责分离,提供视图助手和动作过滤器等功能,简化Web应用的开发。尽管在描述中提到Castle....

    Castle官方下载

    4. **Castle MonoRail**:这是一个轻量级的MVC(模型-视图-控制器)Web应用框架,提供了一种更简洁、更可测试的替代ASP.NET Web Forms的方式。MonoRail强调强类型、约定优于配置以及面向行为的编程。 关于"Castle...

    ASP.NET样板项目ABP框架的特性总结

    5. **数据有效性验证**:除了Asp.NET MVC的Action方法参数验证,ABP还扩展到了Application层,确保整个业务流程中的数据有效性。 6. **日志记录**:ABP集成了日志记录功能,可以自动记录程序异常和其他关键事件,有...

    Castle3.0卷3

    Castle项目是一个开源的.NET框架集合,它包含多个组件,如Castle Windsor——一个强大的依赖注入容器,Castle ActiveRecord——提供对象关系映射(ORM)功能,以及Castle MonoRail——一个用于ASP.NET的轻量级MVC...

    ABP(2.02)框架相关Demo代码以及报错处理和中文说明手册

    基于最新的.NET技术 (目前是ASP.NET MVC 5、Web API 2、C# 5.0,在ASP.NET 5正式发布后会升级) 实现领域驱动设计(实体、仓储、领域服务、领域事件、应用服务、数据传输对象,工作单元等等) 实现分层体系结构...

    SimpleTaskSystem包含NuGet

    ASP.NET MVC 5、Web API 2、C# 5.0 DDD领域驱动设计 (Entities、Repositories、Domain Services、Domain Events、Application Services、DTOs等) Castle windsor (依赖注入容器) Entity Framework 6 \ ...

    PetShop_Model_DAL.rar_CASTLE_Castle mod_activeRecord_castle d

    在这个PetShop的示例中,我们还可以学习到如何将Castle ActiveRecord与其他ASP.NET组件(如控制器、服务层)集成,以实现MVC架构。通过这种方式,我们可以清晰地划分职责,提高代码的可维护性和可扩展性。 总结来说...

    AbpConsole.rar

    ASP.NET MVC 5、Web API 2、C# 5.0 DDD领域驱动设计 (Entities、Repositories、Domain Services、Domain Events、Application Services、DTOs等) Castle windsor (依赖注入容器) Entity Framework 6 \ ...

    monorail的小例子

    Monorail,中文名单轨列车,是针对.NET平台的一个早期的开源MVC(Model-View-Controller)框架,由 Castle Project 开发并维护。它为.NET开发者提供了一种轻量级、灵活且功能丰富的替代方案,以实现Web应用程序的...

    Castle-bin-net-2.0.rar

    4. **Castle MonoRail**:虽然不在当前压缩包内,但值得提及的是,Castle MonoRail是一个Web MVC框架,它为.NET开发者提供了一种替代ASP.NET的轻量级、灵活的开发方式,强调了强类型和约定优于配置的原则。...

    ABP源码分析

    - **Abp.Web.Mvc**: 针对ASP.NET MVC应用提供了集成支持。 - **Abp.Web.Api.Odata**: 支持ASP.NET Web API OData查询。 - **Abp.Web.SignalR**: 集成了SignalR,提供了实时通信功能。 ##### 1.3 相对独立的模块 - ...

Global site tag (gtag.js) - Google Analytics