NHibernateORM工具使用LLBL Gen 3.1,它内置了NHibernate设计器。从生成的代码来看,它借助于FluentNHibernate这个框架提供的功能,把数据库字段与实体属性的映射移到.NET代码中,映射由ORM设计器来维护。
先看数据库的内容,Agent表定义如下
执行查询命令的结果如下,这一句是为了验证之后写的ORM语句的正确性。
启动LLBL Gen,创建一个基于NHiberate的项目,连接数据库
注意:SQL Server可以把(local)和.作为当前的机器名,但是MySQL不认识它,要用localhost
之后再Category Explorer窗体中,点击菜单Reverse-engineer Tables to Entity Definitions来获取实体定义
最终的项目结构如下图所示
F7,生成项目代码,输入顶层的命名空间Paradox.BusinessLogic,生成了Model和Persistence两个项目
项目的解决方案视图如下
Model是实体的定义,Persistence包含实体与数据库的映射定义,它引用了NHibernate和FluentNHibernate。
FluentNHibernate推崇的处理映射的解决办法是用代码文件,请查看FluentNHibernate的文章了解详细内容。
写一个测试数据库读取的方法
using (ISession session = SessionManager.OpenSession())
{
Agent jack = session.Get<Agent>("Jack");
string description = jack.Description;
}
运行程序,即可得到结果。
来分析一下LLBL Gen的NHibernate设计器生成的代码的Persistence项目中,有个SessionManager类
public static partial class SessionManager
{
static SessionManager()
{
_sessionFactory = Fluently.Configure()
.Database(MySQLConfiguration.Standard
.ConnectionString(c => c.FromConnectionStringWithKey("ConnectionString.MySql (MySqlDirect)"))
.ProxyFactoryFactory("NHibernate.ByteCode.Castle.ProxyFactoryFactory,NHibernate.ByteCode.Castle"))
.Mappings(m => m.FluentMappings.AddFromAssembly(typeof(SessionManager).Assembly))
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return _sessionFactory.OpenSession();
}
public static ISessionFactory SessionFactory
{
get { return _sessionFactory; }
}
}
如果不用FluentNHibernate的方法,可能需要写这样的配置文件
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
<property name="connection.connection_string">User Id=root;Password=123;Host=JAMESLI;Database=ctu;Persist Security Info=True;</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
</session-factory>
</hibernate-configuration>
现在这一部分配置内容,已经被移动到C#代码中去了。Model项目中的实体定义Agent,会在Persistence项目中对应一个AgentMap,它的代码定义如下
public partial class AgentMap : ClassMap<Agent>
{
public AgentMap()
{
Table("`agent`");
OptimisticLock.None();
LazyLoad();
Id(x=>x.Name)
.Access.CamelCaseField(Prefix.Underscore)
.Column("Name")
.GeneratedBy.Assigned();
Map(x=>x.Description).Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.Position).Access.CamelCaseField(Prefix.Underscore);
AdditionalMappingInfo();
}
partial void AdditionalMappingInfo();
}
这是FluentNHibernate框架的知识点,请参考FluentNHibernate了解更多的内容。
LLBL Gen 3.x系列的卖点之一是,一个设计器,支持多套ORM框架。比如,支持Entity Framework,NHibernate以及它本身的LLBL Gen Runtime。到目前为止,官方站点还没有加入NHibernate的Sample, 很难找到一个可以完整运行的例子程序。在经过了众多ORM框架的激烈竞争后,对于已经采用了NHibernate框架的公司,可能都自己创作出了生成映射文件工具,比如用Code Smith或是自定义工具。对于没有用NHibernate的公司,第一次就把产品架设到LLBL Gen 1.0版本的NHibernate设计器及其工具上,有些风险。对于已经使用了其他的ORM框架的公司,如果要移植到NHibernate这个框架上,可以考虑尝试一下LLBL Gen 3.x的设计器。
当然,最稳妥的办法还是跟随微软,老老实实的使用它的Entity Framework,避免移植ORM API带来的痛苦。