NHibernate测试的几个小问题
在使用NHibernate时,我发现有许多陷阱,看似微不足道,如果不明白,就会阻碍我们的开发,乃至于影响到开发效率,成为开发的拦路虎。
1、首先是映射的实体类,例如Customer类。由于我采用DDD的方式,将领域逻辑也放入到该实体类中,且通过构造函数传入了一个Repository对象,代码如下:
private ICustomerRepository m_repository;
public virtual int CustomerID {
get;
set;
}
public virtual string Name {
get;
set;
}
public virtual DateTime Birthday {
get;
set;
}
public virtual string Address {
get;
set;
}
public Customer(ICustomerRepository repository) {
m_repository = repository;
}
public Customer Load(int customerID) {
return m_repository.Load(customerID);
}
}
这样的定义会导致无法进行Mapping,会抛出NHibernate.InvalidProxyTypeException异常。原因在于如果实体类定义了一个带参的构造函数,则必须显式地定义一个无参的构造函数。此外,定义在Customer类中的方法,同样必须加上virtual关键字。
}
public virtual Customer Load(int customerID) {
return m_repository.Load(customerID);
}
2、如果使用Visual Studio Team Suite自带的测试框架,则会带来无法找到hibernate.cfg.xml文件的问题。在一般的测试框架下,我们可以将该文件的Copy to output directory属性设置为“copy always”即可。但由于VSTS自带的测试框架会将相关文件放到自动生成的TestResult下的临时文件夹中。因此,可能会抛出如下的异常:
NHibernate.Cfg.HibernateConfigException: An exception occurred during configuration of persistence layer. ---> System.IO.DirectoryNotFoundException: 未能找到路径“C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies;PrivateAssemblies\hibernate.cfg.xml”的一部分。
一个简单的解决方案时将hibernate.cfg.xml拷贝到TestResult目录下,并将构建SessionFactory对象的方法修改为:
好在这只是为了测试而做,所以方案变得如此丑陋,也是可以接受的。
3、关于hbm文件。一般来说,我们需要将实体对象的hbm文件例如customer.hbm.xml文件的Build Action属性设置为Embedded Resource即可。若要验证该属性的设置是否生效,可以通过Reflector查看该程序集下的Resource。如下图:
然而,如果hibernate.cfg.xml的设置有错,仍然会抛出如下异常:NHibernate.MappingException : No persister for: DomainLayer.Entities.Customer。
我们需要在hibernate.cfg.xml文件中增加<mapping>:
<hibernate-configurationxmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="NHibernate.Test">
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">
Data Source=.\SQLEXPRESS;Initial Catalog=EBusiness;
Integrated Security=True;Pooling=False
</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">60</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="DomainLayer"/>
</session-factory>
</hibernate-configuration>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?