黄忠成

風雪之閣 - i live,so i writing

黃忠成ID:Code6421
153208次访问,排名491好友0人,关注者23
coding
Code6421的文章
原创 95 篇
翻译 0 篇
转载 0 篇
评论 221 篇
Code6421的公告
關於我:

黃忠成

  • 資深.NET 技術顧問
  • Run! PC 雜誌專欄作者
  • 程序員雜誌文章作者
  • PC Magazine 雜誌專欄作者
  • MSDN 專欄作者
  • MSDN 特約專屬講師
  • Microsoft .NET專屬講師
  • 台灣微軟最有價值專家(MVP 2008)
  • 台灣微軟特約技術顧問


  • 批評,指教,鼓勵, 請 寫信給我
    轉載文章請使用連結模式,
    請勿整篇Copy! 謝謝!


    我所提供的教育訓練:

    Windows Forms
    ASP.NET 2.0
    如有課程需要,請與我聯絡!

  • 我的著作:

  • 最近评论
    chenyong365:我一定会买一本.
    programlin:>>瀏覽器與Office有著同樣的命運,就是最後都會變成一個載體,趨近於OS的地位

    果然是英雄所見略同.
    上次看到一篇文章,大致上的內容是Microsoft正在積極規劃下一代的作業系統,不是Windows,而是一個完全跳脫出Windows概念的新OS.
    我猜想最近這幾年Microsoft推.Net,SOA架構與Windows Live都是……
    programlin:>>瀏覽器與Office有著同樣的命運,就是最後都會變成一個載體,趨近於OS的地位

    果然是英雄所見略同.
    上次看到一篇文章,大致上的內容是Microsoft正在積極規劃下一代的作業系統,不是Windows,而是一個完全跳脫出Windows概念的新OS.
    我猜想最近這幾年Microsoft推.Net,SOA架構與Windows Live都是……
    programlin:>>瀏覽器與Office有著同樣的命運,就是最後都會變成一個載體,趨近於OS的地位

    果然是英雄所見略同.
    上次看到一篇文章,大致上的內容是Microsoft正在積極規劃下一代的作業系統,不是Windows,而是一個完全跳脫出Windows概念的新OS.
    我猜想最近這幾年Microsoft推.Net,SOA架構與Windows Live都是……
    Code6421:to gutes,

    呃..我也不知道怎麼辦....我書的出版權是在金禾,
    不過金禾.....你也知道...Orz
    文章分类
    收藏
      相册
      风雪之阁
      朋友
      LOLOTA
      Moli
      Will 保哥
      匡正
      小朱
      董大偉
      賴榮樞
      存档
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 關於第四章中,SQL指令何時執行小方框的補充說明收藏

      新一篇: LINQ To Objects 的資料來源 | 旧一篇: 極意之道- .NET Framework 3.5 資料庫開發聖典 (相關資訊彙集 會不時更新)

        
      關於第四章中,SQL指令何時執行小方框的補充說明
      文/黃忠成
       
       
         在【極意之道- .NET Framework 3.5 資料庫開發聖典 ASP.NET】一書中,我於第四章,4-36頁處放上SQL指令何時執行的小方框,裡面的程式證明了當對同一LINQ To SQL回傳值下達多次LINQ  Expression運算式時,只有第一次會被轉成SQL指令後送往資料庫執行。
       但這點與前面提及的Distinct、Count、Skip、Take的函式之用法形成了概念上的衝突,例如下面的Distinct函式用法。
      var result = (from s1 in context.Order_Details
                   where s1.ProductID == 42 select s1.OrderID).Distinct().Count();
      依據4-B01的程式結果看來,Distinct函式應該會先被執行,而Count函式會進入LINQ To Objects的範圍,但就事實而言,Distinct及Count函式都會被組合為單一SQL指令。
      SELECT COUNT(*) AS [value]
      FROM (
          SELECT DISTINCT [t0].[OrderID]
          FROM [dbo].[Order Details] AS [t0]
          WHERE [t0].[ProductID] = @p0
          ) AS [t1]',N'@p0 int',@p0=42
      那究竟是什麼,讓這兩個程式產生不同的結果呢?
        事實上,這是因為4-B01的程式使用IEnumerable為函式間傳遞之型別所致,對於編譯器來說,並不會以物件的原始型別來推算呼叫的Extension Method,而是以最終型別,意思是,當你將LINQ To SQL的回傳值轉型為IEnumerable<T>後,那麼呼叫Where時,編譯器將決議成呼叫System.Linq.Enumerable中的Where函式,而非原本的IQueryable<T>中的Where函式。
       所以,因為明白轉型成IEnumerable後,使得編譯器將後續的LINQ Expression全轉成了LINQ To Objects的呼叫了。
       要正確完成累進式查詢的方式,是將程式4-B01中的IEnumerable<Customer>全換成IQueryable<Customer>。
      static void NestedQuery()
      {
            NorthwindDataContext context = new NorthwindDataContext ();
            context.Log = Console.Out;
            var fquery = GetFirstQuery(context);
            var ret = DoSecondQuery(context, fquery);
            foreach (var item in ret)
               Console.WriteLine(item.CustomerID);
      }
       
      static IQueryable<Customer> GetFirstQuery(NorthwindDataContext context)
      {
            IQueryable<Customer> result = from s1 in context.Customers select s1;
            return result;
      }
       
      static IQueryable<Customer> DoSecondQuery(NorthwindDataContext context,
                                                IQueryable<Customer> firstQuery)
      {
             var result = from s1 in firstQuery
                          where s1.CustomerID == "VINET"
                            select s1;;
              return result;
      }
       這個例子告訴我們一件很重要的事,如果你打算將LINQ的回傳值傳遞到另一個函式,或是回傳,要謹慎選擇型別,因為不同的型別,會影響後續使用LINQ時,編譯器如何決定呼叫的Extension Method,最後造成難以查覺的錯誤。
       如果在撰寫LINQ/LINQ To SQL的通用函式時,不得已需要使用IEnumerable<T>(因為這是LINQ回傳值的通用基礎介面),也要加上依據實體介面來轉型的動作,如下例:
      static void NestedQuery()
      {
           DataClasses1DataContext context = new DataClasses1DataContext();
           context.Log = Console.Out;
           var fquery = GetFirstQuery(context);
           var ret = DoSecondQuery(fquery);
           foreach (var item in ret)
              Console.WriteLine(item.CustomerID);
      }
       
      static IEnumerable<Customers> GetFirstQuery(DataClasses1DataContext context)
      {
            IEnumerable<Customers> result = from s1 in context.Customers select s1;
            return result;
      }
       
       static IEnumerable<Customers> DoSecondQuery(IEnumerable<Customers> firstQuery)
      {      
             IEnumerable<Customers> result = null;
             if (firstQuery is IQueryable<Customers>)
                 result = from s1 in (IQueryable<Customers>)firstQuery
                          where s1.CustomerID == "VINET"
                          select s1;
              else
                 result = from s1 in firstQuery
                          where s1.CustomerID == "VINET"
                          select s1;;
              return result;
      }
       
       

      发表于 @ 2008年04月21日 22:39:00|评论(loading...)|编辑

      新一篇: LINQ To Objects 的資料來源 | 旧一篇: 極意之道- .NET Framework 3.5 資料庫開發聖典 (相關資訊彙集 會不時更新)

      评论:没有评论。

      发表评论  


      登录
      Csdn Blog version 3.1a
      Copyright © Code6421