NHibernate2.0已经发布了。但不知为什么hibernate首页放的链接带是1.2的,要找回原来下载的地址似乎也找不到了。不知是换了还是什么原因。
今天试了一下Access数据库,看会不会有什么惊喜。结果很失望,还是什么都没有。找回1.0版本的MsAccess2000Dialect加入到2.0的源代码里重新编译,有错误。修改这些错误时,发现MsAccess2000JoinFragment继承自ANSIJoinFragment已不大合适了,因为Copy方法不允许重载了,于是一并修改了共其基类。
发nuint测试发现查询时多对一只能使用一层,如果多对一对应的类也有一个属性使用了多对一,就会出现错误。看看如下两个映射


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<class name="FaceEntity.FacePicture,FaceEntity" table="FacePicture">
<id name="ID" type="Int32">
<generator class="native" />
</id>
<property name="FileName" type="String" not-null="true" length="50" />
<many-to-one name="FaceGuest" class="FaceEntity.FaceGuest,FaceEntity" column="FaceGuest_ID" />
<property name="UploadDate" type="System.DateTime" not-null="true" />
</class>
</hibernate-mapping>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<class name="FaceEntity.FaceGuest,FaceEntity" table="FaceGuest">
<id name="ID" type="Int32">
<generator class="native" />
</id>
<property name="Title" type="String" not-null="true" length="50" />
<many-to-one name="Owner" class="FaceEntity.FaceUser,FaceEntity" column="Owner_ID" not-null="true" />
<property name="BuildTime" type="System.DateTime" not-null="true" />
</class>
</hibernate-mapping>
查询FacePicture就会提示


System.Data.OleDb.OleDbException : 语法错误 (操作符丢失) 在查询表达式 'this_.Ower_ID=faceuser2_.ID left outer join FaceGuest faceguest3_ on this_.FaceGuest_ID=faceguest3_.ID left outer join FaceUser faceuser4_ on faceguest3_.Owner=faceuser4_.ID' 中。
原因是生成的SQL中有多个Left join,对于Access来说每一层的join要适当的加上“()”才行。跟进了一下MsAccess2000JoinFragment的调用,发现From、Where(Condiction)、Join都由不同的类来管理。MsAccess2000JoinFragment只是join这一部分,而access的括号要从from紧跟的表开始,于是只好放弃修改源代码。
无奈之时,突然想到延迟加载。于是,于是去掉映射的 default-lazy="false",修改类的每个属性使用virtural定义,查询FacePicture时,没有join语句了,象pic.FaceGuest.Owner.Name的语句,将额外生成两条不含join的语句,分别查询FaceGuest、FaceUser。至此access基本可用NHibernate。
这是我修改的Access访问用到的两个类,我加了目录,打开NHinbernate源代码后添加到同名目录下再编译吧。
http://files.cnblogs.com/kevin-Y/MsAccess2000Dialect_2_0.zip
这是我nunit测试的配置的部分节点


<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<bytecode-provider type="null"/>
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property>
<property name="connection.connection_string">
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Test\vs2008\FaceGuest\FaceWeb\DnsShip.mdb
</property>
<property name="dialect">NHibernate.Dialect.MsAccess2000Dialect</property>
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>