ORM設計工具:Mindscape NHibernate Designer,請安裝Mindscape.NHibernateModelDesigner.vsix檔案。
它是一個Visual Studio 2010的外掛程式,運行時效果所示
支援Model frist和Database first兩種開發模式,如所示
Update Model from Database,從資料庫schema更新模型定義
Update Database from Model 則是以實體定義更新資料庫。
設計器會產生一個組件layout檔案,用於設計器工作,一個cs檔案,對應於實體屬性與資料庫欄位對應,Agent內容如下
public partial class Agent
{
public virtual string Name { get; set; }
public virtual string Position { get; set; }
public virtual string Description { get; set; }
static partial void CustomizeMappingDocument(System.Xml.Linq.XDocument mappingDocument);
internal static System.Xml.Linq.XDocument MappingXml
{
get
{
var mappingDocument = System.Xml.Linq.XDocument.Parse(@"<?xml version='1.0' encoding='utf-8' ?>
<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'
assembly='" + typeof(Agent).Assembly.GetName().Name + @"'
namespace='BusinessLogic'
>
<class name='Agent'
table='`Agent`'
>
<id name='Name'
column='`Name`'
>
<generator class='identity'>
</generator>
</id>
<property name='Position'
column='`Position`'
/>
<property name='Description'
column='`Description`'
/>
</class>
</hibernate-mapping>");
CustomizeMappingDocument(mappingDocument);
return mappingDocument;
}
}
}
MappingXml的值,就是我們開發NHibernate時需要配置的對應檔,由設計器維護。
資料庫選用MySQL 5.1。
MySQL 資料表的建立
SQL指令碼如下
DROP TABLE IF EXISTS `ctu`.`agent`;
CREATE TABLE `ctu`.`agent` (
`Name` varchar(40) NOT NULL,
`Position` varchar(45) NOT NULL,
`Description` varchar(45) NOT NULL,
PRIMARY KEY (`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
先查看一下這個表的資料項目,有三筆資料,分別以Jack,Tony,Charles為主鍵
啟動Visual Studio 2010,開啟Server Explorer,建立一個新的MySQL串連
記住這裡要勾選Allow saving password,否則當把表拖動到設計器中時,會出現無法串連的異常
把表CTU拖動到NHibernate設計器中,以完成模型的建立
在設計器中右鍵,調出Get Started功能表項目
,已經寫好了設定檔的主要內容,添加App.config或Web.config檔案,把配置內容拷貝到檔案中
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<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>
在項目的啟動目錄中,添加這2個程式集:NHibernate.ByteCode.Castle.dll和Castle.Core.dll
把Get Started中的NHibernateHelper檔案拷貝到項目中
public static class NHibernateHelper
{
private static ISessionFactory _sessionFactory;
internal static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var configuration = ConfigurationHelper.CreateConfiguration();
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
internal static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
設計如下的測試代碼
[TestMethod]
public void TestFetch()
{
using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
string name = "Tony";
Agent tony = session.Get<Agent>(name);
string fullName = tony.Description;
}
}
啟動調試器,進入方法中,效果如所示
這表明,NHibernate已經成功的從MySQL資料庫中取得了資料記錄。
從.NET 1.1起,NHibernate就是極力推薦的ORM開發工具。因為沒有稱心的ORM設計工具,維護資料庫欄位與實體屬性之間的映射關係非常麻煩,而且容易出錯。商業的ORM工具,賣點之一就是簡化對應檔的設計。不管是用xml檔案或是cs檔案來維護映射,只要維護關係映射簡單,就是很大的進步,如果能熟練操作文章中提到的資料庫與實體映射的內容,用NHibernate來開發ERP/MIS應該是很簡單輕巧的事情。
寫完了這篇文檔,檢查NHibernate文檔,發生有個NHibernate.Tool.hbm2net的軟體,解釋如下
NHibernate.Tool.hbm2net 是 NHibernate 的附加軟體.它使得從hbm.xml對應檔產生原始碼成為可能。
在 NHibernate.Tasks目錄,有一個叫做Hbm2NetTask的工具,你可以用它自動編譯器(使用NAnt)。
溫故而知新,NHibernate擁有很多工具 + 生產力,再推薦一個工具NHibernate Profiler工具
在應用程式中添加對HibernatingRhinos.NHibernate.Profiler.Appender.dll程式集的引用,並在啟動時添加代碼
[TestInitialize]
public void InitializeProfiler()
{
HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfiler.Initialize();
}
HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfiler.Initialize();
以插入跟蹤程式,再啟動之前的測試方法,切換到NHibernate Profiler的介面中即可看到被發送到伺服器的SQL語句。
當然,也可以用SQL Server Profiler來追蹤出問題的SQL語句,舉例說明
SalesOrderEntity salesOrder=session.Get<SalesOrderEntity>(5023);
這是用主鍵來尋找資料記錄,通常不會有問題。反過來,寫兩個SQL來對比一下,請看以下兩條SQL
SELECT * FROM SalesOrder WHERE CustomerId is NULL
SELECT * FROM SalesOrder WHERE CustomerId =’’
這兩句,從SQL的層面來理解,前一句是找出客戶編碼為空白的採購單,後一句是找出客戶編碼為空白的採購單
對應於CustomerId,一般會用string類型來映射。如果有語句將CustomerId 初試化為string.Empty,而另一段代碼
卻沒有初試化CustomerId,意味著CustomerId為null,這兩個ORM語句發送到伺服器中去,就會是兩種不同的WHERE條件,即CustomerId =’’和CustomerId is NULL,也就是發送的ORM語句與實際SQL查詢的結果不一致。
ORM開發中,出現ORM語句的語意與我們設想的SQL不同時,可使用NHibernate Profiler或SQL Server Profiler來追蹤有問題的SQL語句,從而修改ORM的寫法來排除錯誤。