EF和Dapper之爭的關鍵

忽然發現園子裏爲EF和Dapper的事鬧翻了天。(學Java的同窗大概就是Hibernate和MyBatis之爭了)html

講到EF對Mysql的支持,我在一邊偷着樂:還好我用的是NHibernate,對Mysql的支持可好啦,哈哈……sql

咳咳,這樣作固然是不對的,應該批評。我反省三秒鐘,先。數據庫

 

我看了文章,也看了評論(但沒看完)。老實講,我以爲三生石上只有一句話是站得住腳的:編程

真正出現問題的不是 Entity Framework,而是咱們,好吧,就明說了吧:咱們太想念 SQL 語句了!架構

其餘的,嗯,已經有不少人說了不少了,我就不湊熱鬧了。app

 

不知道你們還記不記得我之前說過:工具

雖然咱們有C#這種面向對象的語言,但實際上咱們不少開發人員仍然是「面向數據庫」編程。性能

爲了不引起更大的爭論,我必須首先聲明:單元測試

面向對象和麪向數據庫並沒有優劣高下之分測試

面向對象和麪向數據庫並沒有優劣高下之分

面向對象和麪向數據庫並沒有優劣高下之分

重要的事說三遍。

 

選擇Dapper,甚至ADO.NET拼SQL,本質上就是「面向數據庫」編程。什麼意思呢?全部的開發過程是以數據庫爲基礎的,整個系統的架構是以數據庫的庫表結構爲依託的。當遇到一個業務邏輯的時候,首先想到的是這數據放在哪幾張表裏的,用什麼SQL語句把它們給取出來,而後纔想着怎麼把這些數據封裝成類……這就是我所謂的「面向數據庫」編程。

那麼與之相對的,什麼是「面向對象編程」呢?

忘掉數據庫,尤爲是關係型數據庫,我之前講過,你能夠想象成這數據最終是存放在XML文件裏的、存放在NoSQL裏的、存放在其餘什麼什麼磁盤裏面的。固然,最理想的,是有一個「對象數據庫」,全部的數據都是以對象形式存放的,數據與數據之間就是對象與對象的關係,有繼承有引用,都是Load出來.出來的。總之,SQL語句徹底無論用。因此,遇到一個業務邏輯的時候,首先想到的就是這些數據存放在哪些對象裏面,怎麼加載這些對象……

明白了吧?這纔是「面向對象」的思路!

哪裏有什麼表,哪裏有什麼SQL?咱們眼裏只有對象!萬物皆對象,阿彌陀佛……

 

可是,世上的事情啊,最怕就是這個可是!

沒有「對象數據庫」,只有「關係數據庫」啊?這是一個始終沒法迴避的問題:幾乎全部的企業級應用,都是以關係數據庫爲存儲器的。這下就麻煩了,怎麼辦呢?

面向對象的擁躉們,就推出了ORM(Object Relational Map),在「對象」和關係數據庫「表」之間作一個映射,但願能解決這個問題。你們必定要明白,ORM是O開頭的,其核心其要義,是把object映射成Relational的表,Object是第一位的。而不是不少同窗那樣,把ORM當成一個SQL語句生成器或者SQL語言的封裝,其做用就是「不寫SQL」。不是這樣的,本末倒置了呀,同窗!那麼,從這個意義上講,Dapper就不算是一個ORM(不作定義上的爭論,你們理解意思就行),他就是一個理想的DBHelper而已。

相應的,EF做爲一個沉重的ORM工具,就被嫌棄了。這是天然而然的,我不知道我說明白了沒有,當你的思惟是「面向數據庫」的時候,ORM確實是一種負擔,不只僅是由於它的「沉重」,更由於它遮蔽了SQL實現的細節:看不到SQL,我內心不踏實啊!還要特麼的設個斷點查查log看看生成的SQL啥樣子的,這就憋屈了……

並且ORM在複雜對象映射、複雜查詢的時候,確實會出問題,如今這工具還不能說是完美。

那咋整呢?

 

我以爲這就是一個我的(或者團隊)的喜愛問題了。

「面向數據庫」自己其實沒問題。基於數據庫基於表結構,CRUD,又怎麼啦?迴歸代碼的本質,也符合KISS(Keep It Stupid Simple)原則啊!不可勝數的成功項目都這樣完成的,並且也一直良好運做。相反的,徹底的「面向數據庫」設計架構的,崩了的項目也很多吧?

可是,我我的而言,更傾向於「面向對象」的思路和方向。主要有這麼幾個緣由:

  1. 不喜歡SQL。這恐怕是決定性的緣由,尤爲憎恨存儲過程,尤爲尤爲受不了那種幾百上千行的存儲過程,崩潰了同樣的感受。「面向數據庫」的極致就是「存儲過程編程」,假如都走極端,相比較而言,「面向對象」的極致我以爲都能接受——就所有代碼見不着一行SQL嘛,沒啥。
  2. ORM在不斷的進步。EF我不熟,NHibernate5.0的不少新特性讓我真的是眼前一亮,最鼓舞人心的就是Colletion上進行Query() 能夠生成SQL查詢而不用把整個collection加載進來。這是我期盼了不知多久的一個特性,太爽了!之前不少爲了性能而作的walkaround就不須要了,代碼會很是的清晰。我相信,ORM工具之後會一直進步,直到無限接近於完美,或者誕生「對象數據庫」。「面向數據庫」就根本不須要BLL層。把數據從數據庫取出來,封裝成類,何須呢?畫蛇添足啊,徹底是。就算要封裝,我以爲強類型的DataSet就徹底夠用了。但DateSet這些已經涼了,說白了,「面向數據庫編程」已經就那個樣子了,能用,但沒啥發展了;但ORM,還有不少人不少公司在努力的完善,還有進步的空間。
  3. 太多太多的工具或手段是必須和「面向對象」配合的。好比說單元測試,我不知道其餘人怎麼玩的,反正個人單元測試是隔離了數據庫的,測試用的數據,直接new就OK了,又快又輕巧。混入了SQL語句或存儲過程,必須連着數據庫,這單元測試咋作?我還真不知道。另外的,領域驅動,「面向數據庫」也沒辦法玩,你和「領域專家」講表結構和SQL,人家會崩潰的。
  4. ORM保留了你在特殊狀況下使用原生SQL的權利。實在不行的時候,仍是能夠本身寫SQL的呀!

 

差很少了,我以爲能夠簡單總結一下,但願同窗們:

  • 可以從戰略高度上理解「面向對象」和「面向數據庫」的區別;
  • 明白ORM的不足,但要對ORM的發展抱有信心。

咳咳,這腔調愈來愈像老師了。是的,人人都是程序猿 已經開課好久了,今天是第18講,入門型普及型課程,有興趣的同窗能夠聽一聽,或者給周圍的新人宣傳宣傳,先謝了!

相關文章
相關標籤/搜索