<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      戀戀風(fēng)塵

      Coding is just my hobby……

      博客園 首頁(yè) 新隨筆 聯(lián)系 訂閱 管理

      一、引言

          NHibernate3.0增加了一種新的查詢API——QueryOver。QueryOver構(gòu)建在NHibernate原有的ICriteria API之上,支持Lambda表達(dá)式與擴(kuò)展方法,可編寫類型安全的查詢語(yǔ)句,這樣就克服了ICriteria API字符串硬編碼的弊端,可借助VS提供的智能提示方便代碼輸入,減少輸入錯(cuò)誤。同時(shí)可利用VS等重構(gòu)功能自動(dòng)更新因?qū)嶓w字段名更改而導(dǎo)致的查詢語(yǔ)句的變更,方便代碼構(gòu)。本文主要介紹QueryOver的常見應(yīng)用,并結(jié)合一個(gè)可運(yùn)行的實(shí)例對(duì)各查詢場(chǎng)景進(jìn)行詳盡的闡述。

        時(shí)間過(guò)得真快,離最近一次在博客園寫文章都快2年時(shí)間了。這些年工作是忙不到盡頭,很少有空閑的時(shí)間可以靜下心來(lái)寫博文,空閑時(shí)間有的話也看書、睡覺、跟新技術(shù)去了。不過(guò)有句名言說(shuō)得好:時(shí)間就像女人的乳溝擠擠總會(huì)有的,呵呵。最近剛結(jié)掉一個(gè)項(xiàng)目,利用難得的空隙機(jī)會(huì)研究了一下QueryOver,基本上實(shí)踐了項(xiàng)目中的大部分查詢場(chǎng)景,并計(jì)劃在后面的新項(xiàng)目中使用QueryOver。

            只要熟悉ICriteria API與LINQ,玩玩QueryOver并不難,如果有個(gè)現(xiàn)成的詳實(shí)例子就會(huì)節(jié)省不少學(xué)習(xí)時(shí)間,但是網(wǎng)上關(guān)于QueryOver的可運(yùn)行的實(shí)例很少,再加上NHibernate在線幫助文檔對(duì)QueryOver的介紹一如既往的簡(jiǎn)潔,所以就做了個(gè)實(shí)例來(lái)介紹QueryOver,并在文章最后提供源代碼下載,以給剛接觸QueryOver的朋友分享經(jīng)驗(yàn)。

      二、開發(fā)環(huán)境與工具

            先介紹一下這個(gè)實(shí)例的開發(fā)環(huán)境與工具:

      三、實(shí)例場(chǎng)景

            為便于理解與掌握,舉個(gè)故意簡(jiǎn)化的實(shí)例:客戶(Customer)與訂單(Order),一個(gè)客戶可以下多個(gè)訂單。實(shí)體類的代碼如下: 

      (1)實(shí)體基類: Entity

       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 
       6 namespace MyWorkShop.Model.Entities
       7 {
       8     public abstract class Entity<TId>
       9     {
      10         public virtual TId Id { getprotected set; }
      11     }
      12 }

        (2)客戶類:Customer,映射的數(shù)據(jù)表為MyWorkShop_Customer

       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 
       6 namespace MyWorkShop.Model.Entities
       7 {
       8     public class Customer:Entity<int>
       9     {
      10         public virtual string Name { getset; }
      11         public virtual string Address { getset; }
      12         public virtual string Phone { getset; }
      13     }
      14 }

       (3)訂單類:Order,映射的數(shù)據(jù)表為MyWorkShop_Order

       1 using System;
       2 using System.Collections.Generic;
       3 using System.Linq;
       4 using System.Text;
       5 
       6 namespace MyWorkShop.Model.Entities
       7 {
       8     //Guid做主鍵
       9     public class Order : Entity<Guid>
      10     {
      11         //下單客戶
      12         public virtual Customer Customer { getset; }
      13         //下單時(shí)間
      14         public virtual DateTime OrderedDateTime { getset; }
      15         //訂單金額
      16         public virtual Decimal? Amount { getset; } 
      17     }
      18 }

       四、查詢場(chǎng)景

       1. 篩選數(shù)據(jù)(Restriction)

       (1)根據(jù)客戶姓名查找客戶,假設(shè)客戶姓名唯一

       1 public Customer GetByName(string customerName)
       2 {
       3     Customer entity = null;
       4             
       5     using (var session = NHibernateSession)
       6     using (var transaction = session.BeginTransaction())
       7     {
       8        
       9         entity = session.QueryOver<Customer>()
      10             .Where(c => c.Name == customerName)
      11             .SingleOrDefault();
      12 
      13         transaction.Commit();
      14     }
      15     return entity;
      16 }

      輸出的SQL:

      SELECT this_.Id as Id5_0_, this_.Name as Name5_0_, this_.Address as Address5_0_, this_.Phone as Phone5_0_ FROM MyWorkShop_Customer this_ WHERE this_.Name = @p0;@p0 = 'Name' [Type: String (50)]

      代碼說(shuō)明:

      • 篩選條件調(diào)用Where方法,使用Lambda表達(dá)式“=> c.Name == customerName”,這樣就消除了ICriteria的字段名字符串硬編碼的問題;
      • 返回單個(gè)值調(diào)用SingleOrDefault(),若查詢結(jié)果不唯一則拋出異常NHibernate.NonUniqueResultException。

      (2)根據(jù)客戶地址查找多個(gè)客戶

       1 public IEnumerable<Customer> GetByAddress(string address)
       2 {
       3     IEnumerable<Customer> list = null;
       4 
       5     using (var session = NHibernateSession)
       6     using (var transaction = session.BeginTransaction())
       7     {
       8         list = session.QueryOver<Customer>()
       9             .Where(c => c.Address == address)
      10             .List();
      11 
      12         transaction.Commit();
      13     }
      14 
      15     return list;
      16 }

       輸出的SQL:

      SELECT this_.Id as Id5_0_, this_.Name as Name5_0_, this_.Address as Address5_0_, this_.Phone as Phone5_0_ FROM MyWorkShop_Customer this_ WHERE this_.Address = @p0;@p0 = 'Address' [Type: String (100)]

      代碼說(shuō)明:

      •  查詢多條數(shù)據(jù)調(diào)用List()方法。

       (3)根據(jù)客戶姓名模糊查找客戶

       1 public IEnumerable<Customer> GetByLikeName(string likeName)
       2 {
       3     IEnumerable<Customer> list = null;
       4 
       5     using (var session = NHibernateSession)
       6     using (var transaction = session.BeginTransaction())
       7     {
       8         list = session.QueryOver<Customer>()
       9             .WhereRestrictionOn(o => o.Name).IsLike(likeName, MatchMode.Anywhere)
      10             .List();
      11 
      12         transaction.Commit();
      13     }
      14 
      15     return list;
      16 }

      輸出的SQL:

      SELECT this_.Id as Id5_0_, this_.Name as Name5_0_, this_.Address as Address5_0_, this_.Phone as Phone5_0_ FROM MyWorkShop_Customer this_ WHERE this_.Name like @p0;@p0 = '%e%' [Type: String (50)]

       代碼說(shuō)明:

      •  對(duì)于某些SQL函數(shù)與操作符(比如like、between...and...),沒有直接對(duì)應(yīng)的Lambda表達(dá)式,需要先使用WhereRestrictionOn方法指定篩選條件的列,然后再調(diào)用相應(yīng)的方法指定篩選條件;
      • IsLike方法指定字符串匹配查找。

       (4)查找金額在指定范圍內(nèi)的訂單

      2 public IEnumerable<Order> GetByAmount(decimal minAmount, decimal maxAmount)
       3 {
       4     IEnumerable<Order> list = null;
       5 
       6     using (var session = NHibernateSession)
       7     using (var transaction = session.BeginTransaction())
       8     {
       9         list = session.QueryOver<Order>()
      10             .Where(o => o.Amount >= minAmount)
      11             .And(o => o.Amount <= maxAmount)
      12             .OrderBy(o => o.Amount).Desc
      13             .List();
      14 
      15         transaction.Commit();
      16     }
      17 
      18     return list;
      19 }

       輸出的SQL:

      SELECT this_.Id as Id8_0_, this_.CustomerId as CustomerId8_0_, this_.OrderedDateTime as OrderedD3_8_0_, this_.Amount as Amount8_0_ FROM MyWorkShop_Order this_ WHERE this_.Amount >= @p0 and this_.Amount <= @p1 ORDER BY this_.Amount desc;@p0 = 100 [Type: Decimal (0)]@p1 = 200 [Type: Decimal (0)]

       代碼說(shuō)明:

      • 多個(gè)條件可使用Where...And...逐個(gè)指定,也可以在一個(gè)Where方法中指定,比如上面的條件可以寫成Where(o => o.Amount >= minAmount && o.Amount <= maxAmount);
      • 排序使用OrderBy,升序降序使用Asc與Desc。

      2.連接(Join)

      (1)內(nèi)連接:根據(jù)客戶姓名查找訂單

       1 public IEnumerable<Order> GetByCustomerName(string customerName)
       2 {
       3     IEnumerable<Order> list = null;
       4 
       5     using (var session = NHibernateSession)
       6     using (var transaction = session.BeginTransaction())
       7     {
       8         list = session.QueryOver<Order>()
       9             .OrderBy(o=>o.Amount).Desc
      10             .Inner.JoinQueryOver<Customer>(o => o.Customer)
      11             .Where(c => c.Name == customerName)            
      12             .List();
      13 
      14         transaction.Commit();
      15     }
      16 
      17     return list;
      18 }

       輸出的SQL:

      SELECT this_.Id as Id8_1_, this_.CustomerId as CustomerId8_1_, this_.OrderedDateTime as OrderedD3_8_1_, this_.Amount as Amount8_1_, customer1_.Id as Id9_0_, customer1_.Name as Name9_0_, customer1_.Address as Address9_0_, customer1_.Phone as Phone9_0_ FROM MyWorkShop_Order this_ inner join MyWorkShop_Customer customer1_ on this_.CustomerId=customer1_.Id WHERE customer1_.Name = @p0 ORDER BY this_.Amount desc;@p0 = 'Name' [Type: String (50)]

       代碼說(shuō)明:

      • .Inner.JoinQueryOver指定內(nèi)連接,如果省略Inner僅寫JoinQueryOver默認(rèn)就是內(nèi)連接;
      • .Left、.Right則分別為左外連接、右外連接
      (2)使用別名進(jìn)行內(nèi)連接:根據(jù)客戶姓名查找訂單
       1 public IEnumerable<Order> GetByCustomerNameViaAlias(string customerName)
       2 {
       3     //定義用于內(nèi)連接的別名變量,該變量必須賦值為null
       4     Customer customer = null;
       5 
       6     IEnumerable<Order> list = null;
       7 
       8     using (var session = NHibernateSession)
       9     using (var transaction = session.BeginTransaction())
      10     {
      11         list = session.QueryOver<Order>()
      12             .JoinAlias(o => o.Customer, () => customer) //指定別名customer
      13             .Where(() => customer.Name == customerName)
      14             .List();
      15 
      16         transaction.Commit();
      17     }
      18 
      19     return list;
      20 }
       輸出的SQL:

             同上,略

       代碼說(shuō)明:
      •  可以通過(guò).Inner.JoinQueryOver來(lái)顯式進(jìn)行內(nèi)連接,也可以通過(guò).JoinAlias創(chuàng)建連接別名進(jìn)行連接;
      •  連接別名變量在QueryOver使用之前定義,并且必須賦null值。

      五、總結(jié)     

            與ICriteria API相比,個(gè)人認(rèn)為QueryOver并不見得會(huì)提高代碼的可讀性,但QueryOver解決了

      ICriteria API字符串硬編碼的問題,從而減少代碼輸入的錯(cuò)誤,大大提高了代碼重構(gòu)的能力,因此用QueryOver取代ICriteria API是值得的。

             本文通過(guò)一個(gè)簡(jiǎn)單的實(shí)例,介紹了QueryOver進(jìn)行條件篩選(Restriction)、連接(Join)等常見場(chǎng)景的應(yīng)用,在下一篇文章中將介紹投影(Projection)、把投影結(jié)果轉(zhuǎn)成DTO、分頁(yè)、子查詢(Subquery)等。

      六、參考資料

       [1] NHibernate關(guān)于QueryOver的在線幫助文檔

       [2] NHibernate 3.0 Cookbook    P130-137

      七、實(shí)例源代碼下載

            源代碼下載

      八、實(shí)例項(xiàng)目說(shuō)明

      1. 項(xiàng)目組織結(jié)構(gòu)

      • MyWorkShop.Model項(xiàng)目:創(chuàng)建實(shí)體類與DTO;
      • MyWorkShop.Data項(xiàng)目:創(chuàng)建數(shù)據(jù)訪問接口;
      • MyWorkShop.Data.NHibernate項(xiàng)目:定義數(shù)據(jù)訪問的NHibernate實(shí)現(xiàn),包含文中所列舉的各查詢方法;
      • MyWorkShop.Data.NHibernate.Test項(xiàng)目:對(duì)MyWorkShop.Data.NHibernate項(xiàng)目中各數(shù)據(jù)訪問方法進(jìn)行測(cè)試。

      2. 測(cè)試數(shù)據(jù)庫(kù)     

            測(cè)試數(shù)據(jù)庫(kù)名為MyWorkShop,數(shù)據(jù)庫(kù)文件位于db文件夾中,附加數(shù)據(jù)庫(kù)文件即可;當(dāng)然也可手工創(chuàng)建名為MyWorkShop的數(shù)據(jù)庫(kù)。

      3. NHibernate配置文件

            hibernate.cfg.xml位于MyWorkShop.Data.NHibernate.Test項(xiàng)目中的,可根據(jù)自己的運(yùn)行環(huán)境進(jìn)行相應(yīng)的配置。


      posted on 2011-05-11 19:46  戀戀風(fēng)塵  閱讀(7132)  評(píng)論(4)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产在线自拍一区二区三区| 国产一区二区三区粉嫩av| 国产高清色高清在线观看| 国产偷国产偷亚洲清高动态图| 成人免费无码大片a毛片| 久久综合国产精品一区二区| 加勒比无码人妻东京热| 精品久久久bbbb人妻| 五月丁香啪啪| 风韵丰满妇啪啪区老老熟女杏吧| 国产成年码av片在线观看| 亚洲精品国产av成人网| 99国产欧美久久久精品蜜芽| 国产精品爱久久久久久久电影| 亚洲日本欧美日韩中文字幕| 成年女人免费v片| 国产精品一二三区蜜臀av| 久久精品国产再热青青青| 特黄aaaaaaa片免费视频| 丝袜美腿亚洲综合第一页| 十八禁午夜福利免费网站| 116美女极品a级毛片| 亚洲精品国产av成人网| 亚洲精品熟女一区二区| 少妇高潮毛片免费看| 久久涩综合一区二区三区| 精品视频在线观看免费观看| 灵寿县| 精品国产av一区二区果冻传媒| 中文字幕在线国产精品| 久久婷婷综合色丁香五月| 欧美国产精品啪啪| 欧美大胆老熟妇乱子伦视频| 宜城市| 欧美日产国产精品| 免费人成网站视频在线观看| 遂川县| 欧洲无码一区二区三区在线观看| 亚洲色最新高清AV网站| 昭通市| 国产精品一二三区蜜臀av|