不少朋友问我Gentle.NET怎么个玩法,因为Gentle.NET的文档是属于看似丰富,实际上看了下来,仍然一头雾水。为了免大家自己再去解读源码的麻烦,所以简单介绍一下快速使用Gentle.NET的使用方法。不过,介绍前请先注意几点:
  首先,请注意的是Gentle.NET至这篇贴子为止,已经到了1.2.6版本,但这并不意味着Gentle.NET是非常成熟与非常成功的组件,它与NHibernate相比只是半斤八两,各有自己的特色,但都有不少的问题存在。这一些问题有些是与O/R Mapping组件自身的原理有关,有一些是与组件本身的设计思想有关,还一些就是代码中存在的BUG,说放心使用的话,不要顾忌什么的话,这说不出口,但如果说因为它们可能存在不少问题就不去用用的话,就是因噎废食。因为我在博客上说Gentle.NET有一些BUG,于是就有朋友回复说那么不敢用了。其实,什么软件没有BUG呢?这是开放源码的组件,有问题可以自己去解决,从而提高自己的开发能力,这总比在遇到商业组件的BUG时,只有望洋兴叹的好(诸如XPO之类虽属精品,BUG也不见得就比开源的更少)。因此,无论使用什么开源组件,保持一个正确的心态是重要的。
  其次,不要为了OO而OO,在实际项目中,如何充分利用现有资源,做到最大化效率的成功生产与维护间的平衡才是所有软件开发的目标,不要一切都追求纯粹的OO,一切都追求纯粹的完美。毕竟,就人类现代科技而言是不现实的,我们既然要生存,就要面对现实。

文件夹介绍
  首先,从网上下载Gentle.NET压缩文件后,解压后,可以得到如下文件夹,作用分别解释:
        Build 一看名字就知道是用于代码编译用的,里面包括了Nant编译文件,强名密钥文件,NDoc文档生成文件等。
  Configuration 配置文件,里面包括了App.Config与Gentle.Config两个文件,它们的区别不大,在配置里包括了对Log4Net组件的配置。这些配置文件使用比较方便,至于App.Config就不多说了,Gentle.Config只要放到与项目编译生成程序集相同的目录下就行了,组件自己会去搜寻这个配置文件,当然,除了与程序集在同一个目录下,也可以放在其它位置,具体的详细说明请自己参照帮助文档。
        Contributions 这个是比较有趣的一个文件夹,里面包括了对CodeSmith与MyGeneration两种代码生成器的模板文件,其中它还提供了CodeSmith的文件编辑插件。就模板文件的生成的代码来说,感觉这些自带的两个模板中,MyGeneration模板生成的效果较好,而CodeSmith生成的比较简单,不过,真正在使用时,MyGeneration生成的代码也是不够用的,因此,还是考虑一下CodeSmith,在它的模板的基础上进行修改出自己的模板来比较好。因为CodeSmith的使用比MyGeneration相对要简单和容易,而且功能也比较强,目前CodeSmith在网上可以找到最新可用的是v3.0.7,有心的朋友可以找一下。
     Documentation    这是文档文件夹,里面自然存放是文档,不过,在真正使用时,这玩意还是比较闹腾人的,因为文档对个人的帮助是有,但不大,里面只是把组件中的类都罗列了出来,虽然不少单词都可以望文生义,但不知是不是老外思路与咱们不同,反正经常可以遇到不是你想象的那样的问题。
  Output 这个文件夹比较重要,里面存放的是已经编译的好的程序集(Release版),可以直接拷出来使用。
  Source    源代码文件夹,不用多说

初步下手
         这一步比较让初接触的人郁闷,因为文档上太含糊了。
     实际上,这一步比较简单,首先,Gentle.Common.dll,Gentle.Framework.dll,这两个文件是必须的,把它们放到某个地方,并把Gentle.Config拷贝到将要生成的程序集的目录下。
      然后,根据你要用的数据库类型,修改Gentle.Config文件,并选择相应的dll,也就是选择Gentle.Provider.XXXX.dll这一类的文件,它是组件与数据库之间的连接器,可以根据实际需要进行选择。
   打开Gentle.Config,可以看到
 <Providers>
        <!-- list known provider assemblies; the assembly .dll suffix is optional -->
        <!-- Provider name="CE"         assembly="Gentle.Provider.CE" /-->
        <!-- Provider name="Firebird"   assembly="Gentle.Provider.Firebird" /-->
        <!-- Provider name="Jet"        assembly="Gentle.Provider.Jet" /-->
        <!-- Provider name="MySQL"      assembly="Gentle.Provider.MySQL.dll" /-->
        <!-- Provider name="Oracle"     assembly="Gentle.Provider.Oracle" /-->
        <!-- Provider name="OracleODP"  assembly="Gentle.Provider.OracleODP" /-->
        <!-- Provider name="PostgreSQL" assembly="Gentle.Provider.PostgreSQL" /-->
        <!-- Provider name="SQLite"     assembly="Gentle.Provider.SQLite" / -->
        <Provider     name="SQLServer"  assembly="Gentle.Provider.SQLServer" />
        <!-- Provider name="Sybase"     assembly="Gentle.Provider.Sybase" / -->
        <!-- Provider name="SybaseASA"  assembly="Gentle.Provider.SybaseASA" / -->
    </Providers>

        可以注意到,有一些是注释了的,有一些不是,需要注意的是,配置文件里如果启动了什么连接器,就必须使用相应的DLL,否则无法使用。
  在这里,仅开启了SQLServer的连接器,因此,只需要Gentle.Provider.SQLServer.dll即可
  开启了连接器后,还需要设定默认的连接器,因为Gentle.NET允许开启多个连接器,如果不在配置文件中进行指定的话,就必须在程序中指定,一般情况下,都是用一种数据库,因此,这里可以直接指定,以免麻烦。
        找到
        <DefaultProvider name="SQLServer" connectionString="..." />
        这一行就是默认的连接器的,只需要配置字符串就行了。
  至此,Gentle.NET组件就可以正常工作了。
  现在,打开数据库,创建一张表,然后用代码生成器生成代码,在网上找个示例来试一下吧。

使用中的问题
  上面的入手成功后,离真正使用还有一段距离,不过,参看一下下面的解说,虽然不至于就能把Gentle.net玩熟,但起码大部分问题可以解决。
   使用O/R Mapping组件(我没拿它当O/R用,完全是当一个数据库访问组件),主要是为了省心省力省时,免除CURD带来的严重困扰,同时在一定情况下还能保证效率,因此,SQL是必要的。偶尔不需要性能的时候,花费些时间,但可以获得更有效、更清晰地处理,因此,对DataTable,DataView的支持也是必要的。
  很不幸的是,Gentle.NET都支持了......
        在组件里,有一个叫SqlResult的与ObjectFactory的类可以搭配使用,不要小看它们呀,它可以让你直接使用SQL语句,什么,这样不行?谁说的?我就这样干。
  在不少的O/R组件中,都提供了Criteria一类的玩意(当然,Gentle.NET也支持它),让你可以用类的方式来描述SQL的条件语句,这样可以最大程序上保证组件对异种数据库的支持。
  可是,语法之难写,让人郁闷。别跟我说:
        Criteria criteria = session.createCriteria(TUser.class);
        criteria.add(Expression.eq("groupId",new Integer(2))); 
        这样的语法能够给你带来什么快感,如果你说是,我只能抱歉,这一小节你可以跳过去,因为俺觉得自己如果喜欢这种写法就会让自己有受虐倾向。

        因此,我更喜欢在代码生成时,就生成了这样的代码,如:
         private UserList FindUsers(string filter)
         {
               SqlResult sr = Broker.Execute("Select * from User where "+filter);
               return ObjectFactory.GetCollection(typeof(User),sr) as UserList;
         }
        这样,我就可以堂而皇之的用UserList("groupId>2")来直接返回一个UserList。
  无论什么查询,都可以这样处理,这样处理之后的好处,还包括UserList的特殊处理,可以使用自己采用UserList[i].Name之类的方式进行直接地访问,看起也比较漂亮,可爱的智能提示也可以让大家写起来更佳迅速。