歡迎您光臨本站 註冊首頁

聊聊Linq To Sql集成資料庫語言的優劣(第一篇)

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0
Linq To Sql是Microsoft開發的針對解決data!=object問題的新技術.在筆者的一系列的文章中,對它已經做了大量的介紹.現在,筆者將從經驗的角度,談談它的優劣.

LINQ to DataSet 也可用於查詢從一個或多個數據源合併的數據.這可以使許多需要靈活表示和處理數據的方案(例如查詢本地聚合的數據和 Web 應用程序中的中間層緩存)能夠實現.具體地說,一般報告、分析和業務智能應用程序將需要這種操作方法.

  1、Linq To Sql的優點

  在Linq To Sql推出之前,我們只是把sql語句形成一個string,然後,通過ado.net傳給sql server,返回結果集.這裡的缺陷就是,如果你sql語句寫的有問題,只有到運行時才知道.而且並不所有的人都懂資料庫的.Linq To SQl 在一切圍繞數據的項目內都可以使用.特別是在項目中缺少SQL Server方面的專家時,Linq To SQl的強大的功能可以幫我們快速的完成項目.Linq To SQl的推出,是讓大家從煩瑣的技術細節中解脫出來,更加關注項目的邏輯.Linq To Sql的出現,大大降低了資料庫應用程序開發的門楷,它實質是事先為你構架了數據訪問層,勢必將加快資料庫應用程序的開發進度.Linq To Sql解放了眾多程序員,讓他們的把更多的精力放到業務邏輯以及code上,而不是資料庫.對於初學者來講,Linq To Sql可以讓他們迅速進入資料庫應用程序開發領域,節約了培訓成本.

  Linq To SQl 的實現,是在ado.net和C#2.0的基礎上的.它通過自動翻譯sql語句,並把結果集創建成對象並返回.這裡我們可以看出,發送到SQL Server端的sql語句是Linq To Sql自動生成的.這對不懂sql的人來說,無疑是個福音.第二,Linq To Sql語句是在編譯期間就做檢查的.而不是運行時檢查.這樣,那裡出了問題,可以及時更改,而不是到了運行時才發現問題.第三,Linq To Sql是針對對象操作的,更符合今天的oo呼聲.

  在Linq To SQl 之前,在Java領域有Hibernate,在net領域有NHibernate技術,來實現object/relational 持久和查詢服務.那和NHibernate比起來,它又有那些優勢呢.第一,影射代碼自動生成.VS2008提供了SqlMetal和OR Designer兩個工具來完成此步驟.而在NHibernate中,你不得不自己手工寫.第二,影射代碼有更多的選擇.NHibernate只能把資料庫的信息配置在一個xml中,而Linq To Sql有兩種方式,一個是放到XML中,我們稱為Externl Mapping, 再一種就是以Attribute的形式,存在於各個property中.當然,筆者本人並沒有使用過NHibernate,只是從資料上得到這些消息,無法給出更多的比較.

  2、Linq To Sql的缺點

  很久前,有個網友問到這麼一個問題.他在界面上有個DataView,裡面綁定了一些Column,然後他勾選那一列就按某列排序.其傳回的參數是列的名字.然後問我該怎麼用Dlinq 來實現.

  在以前拼接Sql語句的年代,這個很簡單,一個" order by " string,想按什麼排就按什麼來排.而現在dlinq是用是一個對象的屬性,已經不可能拼接了.我當時給他的答案是這樣的.

以下是引用片段:
private void Methods(string orderId)
  {
   var q = db.Customers.Select(c=>c);
  
   switch(orderId)
   {
   case "ID":
   q = q.OrderBy(c=>c.ID);
   break;
   case "Name":
   q = q.OrderBy(c=>c.Name);
   break;
   default:
   break;
   }
  
   var result = q.ToList();
  }



  我那時也沒有想出一個更好的方案來.而後告訴他去查下Compiled Query,說不定可以找到更方便的.後來我才在這個例子中,看到更方便的.

以下是引用片段:
var query =
   db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
   OrderBy("CompanyName").
   Select("New(CompanyName as Name, Phone)");



  在這裡OrderBy直接接收的就是列的名字.再仔細一看,好像Where里是Linq的語句哎,那OrderBy也該是linq語句.後來,我把CompanyName換成小寫的,一跑過了.莫非真的是列的名字?出個難題吧.找了一個列名,是帶空格的,重新來建這個工程.一跑,錯了!把列名用中國擴號擴起來了,也是錯了.咳,只是動態構造Expression Tree而已,永遠都不能直接接收列的名字.這個例子看著是很簡單,可不知道你有沒有注意到它有一個80多k的Dynamic.cs文件.更有意思的事情是,它的名稱空間是System.Linq.Dynamic.看樣子,ms本來是打算把它加在.net3.5中嗎.不曉得為什麼放到了例子中了.這個名稱空間下,其主要內容就是動態構造Expression Tree. 和Linq To Sql進階系列(七)動態查詢 一文中的方法類似.只是,它還包含了解析字元串部分.



  從上面那個例子中,可以看出,Linq To Sql在這種動態構造語句時,比拼接sql麻煩很多.在Linq To Sql進階系列(七)動態查詢 一文中,筆者極力推薦使用object的查詢.這符合Linq To Sql的設計原則.,它主要是為了解決data!=objects 的問題而產生的.它所有的操作均針對object,那就讓我們使用object的查詢吧.

  當然,依然會有人習慣拼接字元串.我並不認為這是個壞毛病.只是有點不符合oo思想而已.事實上,在Linq To Sql中,你依然可以使用拼接字元串的形式,而不使用它提供的Query Expression. 它提供了這麼兩個介面,一個是,db.ExecuteQuery(string sql); 另一個是,db.ExecuteCommand(string sql); 這兩個函數都是直接接收 sql語句的.習慣拼接的人,依然可以調用它們來實現你的程序.特別是第一個,其返回的就是一個對象的集合,多少還是有點oo思想的.

  看下面的例子:

以下是引用片段:
var products = db.ExecuteQuery(
   "SELECT [Product List].ProductID, [Product List].ProductName "
   "FROM Products AS [Product List] "
   "WHERE [Product List].Discontinued = 0 "
   "ORDER BY [Product List].ProductName; "
   ).ToList();



  它返回的就是product的集合.而不是什麼dataset和datatable之類的.這裡,你可以大膽的使用該函數繼續拼接你的sql吧,再看下面這個:

以下是引用片段:
db.ExecuteCommand("UPDATE Products SET UnitPrice = UnitPrice 1.00");



  它在做批處理的時候,你想不用它,都不行.當然,你如果覺得性能不是問題的話,那就用submitchange方法來做更新好了.簡單明了的說,Linq To Sql在批處理更新的時候,SubmitChange只會一個個的更新.浪費時間資源.而這個介面,恰好滿足了批處理更新或刪除的問題.從這兩個例子,我們可以看出.沒有任何方案是萬能的.各有各的優點.

  3、Linq To Sql的性能

  Linq 的性能已經被好多人提及.Linq To Object 的性能大家討論的比較多些.它確實比自己實現的查找要慢.但是當數據量特別大時,更多是時間是花在分配虛擬內存上了,那麼他們的差別就不是那麼明顯了.Linq To Sql是又如何提升性能的?第一,採用延遲載入(deferred loading)技術.語句是聲明了,但是並不立即執行,而是在真正需要的時候才執行.第二,採用緩存技術.已經取到內存的數據,再依次提取時,會先從緩存中返回,而不是再次訪問資料庫.當然,筆者建議,不要對象的時候,沒有必要使用Linq To Sql.比如,只是填充DataView或DataGrid時,返回dataset或datatable要比用Linq To Sql實現的快很多.

  結論:各種技術都有其自身的優點和缺點.使用什麼樣的技術,完全在於項目對性能和開發進度的要求,以及程序員自身的愛好有關.揚長避短,才是正道.


[火星人 ] 聊聊Linq To Sql集成資料庫語言的優劣(第一篇)已經有635次圍觀

http://coctec.com/docs/linux/show-post-58699.html