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帶來的痛苦。