NHibernate3.0剖析:Query篇之NHibernate.Linq增強查詢
相關文章:NHibernate3.0剖析:Query篇之NHibernate.Linq標準查詢
系列引入
NHibernate3.0剖析系列分別從Configuration篇、Mapping篇、Query篇、Session策略篇、應用篇等方面全面揭示NHibernate3.0新特性和應用及其各種應用程序的集成,基于NHibernte3.0版本。如果你還不熟悉NHibernate,可以快速閱讀NHibernate之旅系列文章導航系列入門,如果你已經在用NHibernate了,那么請跟上NHibernate3.0剖析系列吧。
- NHibernate專題:http://kb.cnblogs.com/zt/nhibernate/
- NHibernate官方站點:http://nhforge.org/
- NHibernate參考文檔:http://nhforge.org/doc/nh/en/
- 獲取NHibernate地址:http://sourceforge.net/projects/nhibernate/
增強查詢概述
NHibernate.Linq除了提供標準查詢運算符外,NHibernate.Linq還專門提供了NHibernate特有的兩個增強查詢方法,分別是立即抓取(EagerFetching)和查詢緩存(QueryCacheable)。
立即抓取(EagerFetching)
如果我們不在Mapping文件中對對象關聯關系設置Lazy="false",默認是延遲加載的,NHibernate3.0提供了四種擴展方法。分別為Fetch及ThenFetch,FetchMany及ThenFetchMany。在查詢時,使用這些方法用于立即加載出關聯對象。
關聯關系默認是延遲加載的,例如下面NHibernate.Linq查詢查詢出所有Customer,其Order集合默認是延遲加載的。
//Code Snippets Copyright http://lyj.cnblogs.com/
var x = session.Query<Customer>().ToList();
使用Fetch立即加載關聯關系,例如立即加載所有Customer對象Order集合。
//Code Snippets Copyright http://lyj.cnblogs.com/
var x = session.Query<Customer>().Fetch(c => c.Orders).ToList();
使用Fetch對象立即加載多個關聯關系,如果一個對象有多種集合,我們可以使用下面方法立即加載多個關聯關系。例如Employee對象有Subordinates及Orders集合,使用下面方法立即加載出所有Employee對象的Subordinates和Orders集合。
//Code Snippets Copyright http://lyj.cnblogs.com/
var x = session.Query<Employee>()
.Fetch(e => e.Subordinates)
.Fetch(e => e.Orders).ToList();
使用Fetch及ThenFetch,FetchMany及ThenFetchMany立即加載嵌套關聯,例如Customer對象有Order集合,Order集合也有多個OrderLines集合,可以使用下面方法全部立即加載出來。
//Code Snippets Copyright http://lyj.cnblogs.com/
var x = session.Query<Customer>()
.FetchMany(c => c.Orders)
.ThenFetchMany(o => o.OrderLines).ToList();
查詢緩存(QueryCacheable)
NHibernate3.0提供了三種擴展方法對查詢緩存(QueryCacheable)的支持。
- Cacheable用于開啟查詢緩存。
- CacheMode用于設置緩存策略。
- CacheRegion用于設置緩存區域。
下面NHibernate.Linq查詢開啟查詢緩存,當執行這句查詢時,首先從QueryCache里面查詢,看看是否存在了,不存在則查詢數據庫后放入QueryCache,存在則直接從QueryCache中獲取。
//Code Snippets Copyright http://lyj.cnblogs.com/
var q = session.Query<Customer>().Cacheable().ToList();
下面Linq查詢開啟查詢緩存,設置緩存區域和策略。
//Code Snippets Copyright http://lyj.cnblogs.com/
var q = session.Query<Customer>()
.Cacheable().CacheRegion("Test")
.CacheMode(CacheMode.Put).ToList();
實例分析
IStatistics接口提供QueryExecutionCount、QueryCachePutCount、QueryCacheHitCount三個屬性用來統計查詢緩存執行數目、Put數目、擊中數目。
注意NHibernate默認不啟用查詢緩存,我們需要額為配置:
//Code Snippets Copyright http://lyj.cnblogs.com/
cfg.SetProperty(Environment.UseQueryCache, "true");
例如下面例子:執行兩次相同的查詢,驗證查詢執行數目為1,Put數目為1,擊中數目為1。
//Code Snippets Copyright http://lyj.cnblogs.com/
[Test]
public void QueryCacheable()
{
SessionFactory.Statistics.Clear();
SessionFactoryImplementor.QueryCache.Clear();
var session = SessionFactory.OpenSession();
//Execution and Put Query
var q = session.Query<Customer>().Cacheable().ToList();
//Get Results from QueryCache
var q2 = session.Query<Customer>().Cacheable().ToList();
SessionFactory.Statistics.QueryExecutionCount.Should().Be.EqualTo(1);
SessionFactory.Statistics.QueryCachePutCount.Should().Be.EqualTo(1);
SessionFactory.Statistics.QueryCacheHitCount.Should().Be.EqualTo(1);
}
如果使用NHibernate Profiler監視上面的測試,可以看到其執行了一條語句,第二條直接使用查詢緩存。
這篇在NHibernate.Linq標準查詢的基礎上,介紹了NHibernate特有的兩個NHibernate.Linq增強查詢立即抓取(EagerFetching)和查詢緩存(QueryCacheable)。下篇繼續。
延伸閱讀
MIKE HADLOW:NHibernate Linq Eager Fetching
Ayende:Eagerly loading entity associations efficiently with NHibernate
希望本文對你有所幫助。