Linq到SQL沒有錯過點? 不是ORM映射器(SubSonic等)次優解決方案?


Answers

讓我先說這個,說我是一個染色的數據庫人。

作為一個總的過度概括 :開發人員不知道SQL。 開發人員並不真正知道SQL。 他們可以寫它,他們可以設計表,但它使他們感到噁心。 當必要的查詢不僅僅是一個簡單的連接時,他們往往會做一些愚蠢的事情。 不是因為開發商很愚蠢 - 因為他們不能被打擾。 他們喜歡生活在一個只能處理一個概念空間的世界, 從對象移動到表格並返回是上下文切換他們不喜歡支付的價格。

這並不意味著他們是壞的或錯誤的; 這意味著有改進的機會。 如果您的客戶(在這種情況下,使用您的框架的開發人員)不喜歡SQL和表 - 給他們一個抽象層,讓他們離開而不處理底層的混亂。

垃圾收集/自動化內存管理是一個重要的邏輯。 是的,開發人員可以處理它; 是的,他們可以編寫沒有它的代碼更好的優化; 但不必處理它,使他們更快樂,更有成效。

Question

我希望社區對Linq to Sql和其他ORM映射器有一些想法。

我喜歡Linq to Sql和在本地開發語言中表達數據訪問邏輯(或一般CRUD操作)的想法,而不必處理C#和SQL之間的“阻抗不匹配”。 例如,要為業務層返回一個ObjectDataSource兼容的Event實例列表,我們使用:

return db.Events.Select(c => new EventData() { EventID = c.EventID, Title = c.Title })

如果我要使用舊的SQL-to-C#構造來實現這一點,那麼必須創建一個Command類,添加EventID參數(使用字符串來描述“@EventID”參數),將SQL查詢字符串添加到Command類,執行該命令,然後使用(cast-type)nwReader [“FieldName”]來提取每個返回的字段值,並將其分配給新創建的EventData類(yuck)實例的成員。

所以, 就是為什麼像Linq / SubSonic /等人。 並且我同意。

但是,從更大的角度來看,我發現了一些錯誤的東西。 我的感覺是,微軟也看到了一些錯誤,這就是為什麼他們要殺Linq到SQL,並試圖將人員轉移到Linq的實體。 只是,我認為微軟在一個糟糕的賭注上翻了一番。

那麼,什麼是錯的?

問題是有架構的宇航員 ,特別是在微軟,看著Linq to Sql,意識到這不是一個真正的數據管理工具:在C#中仍然有許多事情你不能輕鬆做到,他們的目標是修復它。 你看到了Linq to Entities背後的雄心,Linq 革命性的博客文章甚至LinqPad的挑戰

而問題是,它假定SQL是問題。 也就是說,為了減少輕微的不適感(SQL和C#之間的阻抗不匹配),當一個創可貼(Linq to SQL或類似的)可以很好地完成時,微軟已經提出了相當於一個太空套裝(完全隔離)。

據我所知,開發人員非常聰明,掌握關係模型,然後在開發工作中智能地應用它。 事實上,我會​​更進一步說,Linq到SQL,SubSonic等已經太複雜了:學習曲線和掌握SQL本身沒有太大的區別。 由於在可預見的將來,開發人員必須掌握SQL和關係模型,現在我們正面臨著學習兩種查詢/ CRUD語言。 更糟糕的是,Linq通常很難測試(你沒有查詢窗口),從我們正在做的實際工作中移除了一層(它生成SQL),並且對SQL結構的支持(最好)非常笨拙日期處理(如DateDiff),“有”,甚至“分組依據”。

有什麼選擇? 就個人而言,我不需要像Linq to Entities這樣的數據訪問模式。 我寧願在Visual Studio中彈出一個窗口,輸入並驗證我的SQL,然後按下按鈕生成或補充一個C#類來封裝調用。 既然你已經知道SQL,你不喜歡只輸入這樣的東西:

Select EventID, Title From Events Where Location=@Location

並最終得到一個EventData類,A)包含EventID和Title字段作為屬性,B)有一個工廠方法,它將一個'Location'字符串作為參數,並生成一個List <EventData>? 你必須仔細考慮對像模型(上面的例子顯然不涉及這個),但是在消除阻抗不匹配的情況下仍然使用SQL的基本方法吸引了我很多。

問題是:我錯了嗎? 微軟是否應該重寫SQL基礎架構,以便不必再學習SQL /關係數據管理? 他們可以用這種方式重寫SQL基礎結構嗎? 或者你認為在SQL之上的一個非常薄的層,以消除設置參數和訪問數據字段的痛苦是足夠的?

更新我想推廣兩個鏈接到頂端,因為我認為他們捕捉了我所追求的重要方面。 首先,CodeMonkey指出了一篇題為“越南計算機科學”的文章 開始需要一段時間,但是是一個非常有趣的閱讀。 其次,AnSGri指出了Joel Spolsky的一個更為突出的部分: 洩漏抽像法則(Law of Leaky Abstractions) 。 這是不是在主題上,但它是密切的,是一個偉大的閱讀。

更新2:我給了ocdecio“答案”,雖然這裡有很多很好的答案,而“正確的”答案的選擇純粹是主觀的。 在這種情況下,他的回答與我認為是目前技術狀況下最好的做法是一致的。 然而,這是一個我完全期望發展的領域,所以事情可能會改變。 我想感謝每個人的貢獻,我贊成每個人,我認為給了一個深思熟慮的答案。




你應該停止擔心和學習愛ORM。 像這些抽象將幫助我們集中我們的技能,並在該領域取得進展。

還有足夠的空間來利用你已經獲得的功能技能,並將其應用於應用層。 這實際上是LINQ to SQL比其他ORM更強大的優勢之一。

我只能同意其他許多意見。 你節省的時間,你可以專注於改善你的領域模型,並做出更好的應用程序。 而且,一旦您確定了瓶頸,請使用創建優化的SQL。

ORM帶有許多非常好的特性,可能不是很明顯。 有助於避免重複加載項目的身份映射,延遲加載可幫助您用較少的管道來表達域,而工作單元可幫助您跟踪更改並優化數據庫寫入。




如果您希望數據庫在擴展時執行,則必鬚根據數據庫關係模型最佳實踐進行設計和規範化。

如果讓對像模型和ORM指定你的數據模型,那麼你最終會得到一個不規範的數據模型,或者包含對像模型中的工件。

1表= 1類是一個壞主意。

首先,你永遠不會有代表多對多或多對一鏈接表的類。 這些對應於對像模型中的子集合 - 鏈接本身不是對象。

如果您將數據庫視為表來簡單地將對象保存在行中(一種常見方法),並讓應用程序直接訪問表,那麼您將放棄定義數據庫服務的接口層的所有好處,數據庫可用來保護它的外圍。

ORM有它們自己的位置,但是如果使用它們來簡單地保持對像模型中設計的對象,那麼您的數據庫將不會是關係數據庫,並且將不能用作ETL,報告,重構等




作為一個ORM項目的作者,我不得不承認,我對這個問題的回答往往有點偏頗。 在閱讀問題之前,我已經對自己的答案有了一些自己的想法,所以我已經有所了解了。

我會說我開發ORM的原因不是因為SQL和命令式編程之間的“阻抗不匹配”,而僅僅是為了成為數據庫平台不可知的目的。 前一個編寫更多代碼來管理持久性的問題是一個很小的障礙,如果你只與一個數據庫供應商合作,這個問題很容易解決。 成為數據庫平台不可知論者是一個更具挑戰性的問題,假設像我一樣計劃向其他人出售軟件(而不僅僅是在內部使用它),imo對你的業務的盈利能力有更大的影響。

當我幾年前開始使用我的ORM工具時,這個概念在我的首選語言中是不切實際的,我所交談的大多數人都不明白我為什麼要這樣做,社區中一些備受尊敬的聲音和寫作文章一樣多在貿易雜誌上說我已經做了不僅不可能,而且也是不可取的。 一些相同的原因被給出 - 這太複雜了,這是限制性的,並增加了開銷。 現在,同一個社區至少有三個流行的數據庫抽象工具(儘管對ORM這個術語的定義有一些爭論)。 我之所以提到這個,是因為當我開始研究這些工具時,原來的反對意見比現在要重要得多。 在這段時間內,硬件和軟件的基礎技術已經發生了變化,從長遠來看使這些工具變得更加實用。 我的傾向是嘗試從軟件的長遠角度出發,研究可能不太實用的解決方案,但很快就會實現。 所以鑑於我不會把LINQ to Entities算作一個很好的解決方案。

我也傾向於選擇更多的選擇,而不是更少的選擇。 所以,雖然我可能支持開發LINQ to Entities的想法,但我不太容易支持LINQ to SQL,因為LINQ to Entities已經可用了。 對像是做什麼對象的偉大做法,這是毫無疑問的...在我的(也是有偏見的)看來,一個問題發生在人們看到任何給定的工具或軟件模式作為一個“神奇的子彈”,並希望堅持一切必須是這樣的。 眾所周知,關係數據庫在處理某些其他任務方面非常擅長,報表就是一個很好的例子。 所以在我看來,這是一種徒然的手段,堅持一切都必須是實體,因為那樣你就迫使自己使用效率低下的工具。 所以特別是在報告方面,擺脫LINQ to SQL,至少在表面上只使用LINQ to Entities聽起來像是抽象反轉反模式。

所以我想我的答案是這樣的概要:如果您的問題是釘子,請使用錘子 - 如果您的問題是螺絲釘,請使用螺絲刀。




there's沒有問題LINQ,但與那些誰使用它,不理會發生什麼“幕後”

我還是比較喜歡讓我的手臟與SQL。至少i'll exatcly知道發生了什麼。




我不喜歡任何當前的解決方案 - 但我更喜歡更多的選擇在選擇少;-)

我曾經在一個項目的OODBMS不久前,這是最接近正確使用(unfortunatley的產品有一些令人髮指的錯誤和可怕的技術支持) -對象持久化在很大程度上是無形的,在後台處理(通過預處理代碼生成器)和受控通過非常簡單的更新,刪除和查找方法和簡單的容器。

我很樂意看到這一點(也許有些對象的實體模型做這口井已經)再次,與OCL(對象約束語言)作為本地多對象查詢語言




我認為這些背後的邏輯是在框架層構建和運行SQL語句的開銷與系統其他部分的開銷(例如,HTTP請求往返時間要長幾個數量級)相比是微不足道的。

優點 - 快速的開發,適合於語言的查詢而不是逃避字符串等,通常大於缺點。 如果性能是一個問題,那麼你可以稍後進行優化。

我不認為“不需要知道SQL”是一個因素。 任何像樣的開發人員都需要在開發過程中了解SQL。 數據庫抽象層的思想是消除為數據庫查詢生成樣板代碼的工作。

事實上,在我們的Java系統中,我創建了一個代碼生成器實用程序,它使用帶註釋的類並生成一個完整的CRUD API,並處理所有那些隨著時間推移而挑選的古怪事物。 通過編寫一個DAO,創建你的模型和註釋比創建模型更容易。 擴展這樣一個工具,最終得到LINQ或Hibernate或其他ORM DB解決方案。




正如德米特里指出的那樣 ,開發人員不知道SQL。 更確切地說,大多數人都知道 SQL,但不了解它,肯定不喜歡,所以他們傾向於尋找神奇的子彈,創造像Linq這樣的東西的需求,使他們的幻想(嗯,抽象)不會使用與他們喜愛的課程不同的東西。

這是非常糟糕的,因為洩漏抽象的規律總是成立的。

有些ORM解決方案確實很好(如JPA / Hibernate),不是因為使用它們,你不必擔心SQL。 實際上,要有效地使用JPA,你需要對數據庫有非常深入的了解,特別是查詢能力。 好的一點是,他們讓機器做無聊的工作 ,從頭開始自動生成整個數據庫。

Linq to SQL,我認為,並不能解決真正的問題。 這是一種其他的演示,沒有什麼更多。 這可能是好的,雖然它已經過分複雜的語言。 另一方面,Linq to Objects是一個非常有趣的概念,因為它是一種查詢集合的方法。




恕我直言,OR / M不僅是“抽象SQL”或隱藏SQL,或啟用多數據庫支持。

它使您能夠更專注於您的問題領域,因為您必須花更少的時間編寫無聊的CRUD SQL查詢。 另一方面,如果你正在使用一個好的OR / M,這個OR / M應該使你能夠編寫SQL查詢,如果這似乎是必要的。

如果正確使用,OR / M可能是一個強大的工具; 它可以照顧延遲加載,多態查詢/關聯...
不要誤會我的意思; 普通的SQL沒有什麼問題,但是如果你不得不把自己的(精心設計和規範化的)關係模型轉換成一個表達式的面向對象/域模型,那麼我認為你花了很多時間去做管道工。

使用OR / M也並不意味著你作為一個開發人員不應該有SQL的知識。 相反是真實的imho。
了解SQL並知道如何編寫高效的SQL查詢,將使-imho-能夠正確使用OR / M。

我也必須承認,我正在用NHibernate來寫這個。 這是我使用atm的OR / M,我還沒有使用Linq到SQL或Linq到實體(還)。




我想寫這是一個答复@SquareCog回复這裡,但它告訴我,我不得不-1836人物離開了。SO小白這裡,所以道歉,如果我做了這個錯誤。

在18世紀休閒的紳士用來學習科學。當時科學的全部是沒有這樣一個大課題,相當聰明的人無法理解這一切。我指的是一個博學的同胞能夠理解的時間科學思想的全部。

隨著時間的流逝數百科學已經發現了新的領域,每一個研究到這種地步,這些天很少有人能甚至理解科學的一個完整場的全部。

因此,它是與編程。

這些天編程語言領域是足夠大,並且增長速度不夠快,這是盡可能可以合理地預期開發商的知道自己的專用語言(S)的全部。對於也可以預期熟練的編碼器,了解數據庫字段的全部過,包括數據庫設計,原生SQL的細微差別,以及如何運行在不同的數據庫和這些數據庫的管理也可能是要求有點過分了。

我想,這裡的一些反應都是掩飾一些開發大型高性能企業級數據庫的複雜性,知道肯定不剪“SQL語句的少數”。這也就是為什麼大多數大型軟件公司有專門的數據庫開發人員團隊。由於斯特勞斯說,“分而治之”,是有效用的開發和管理大型軟件項目固有的複雜處理的唯一途徑。

開發商不喜歡使用SQL的,因為他們是懶惰或者是因為這讓他們感到“噁心”。因為他們是聰明的,他們不喜歡使用SQL的。他們比任何人都只有誰在SQL會有人提供最高質量的數據庫功能,並且為他們投入的是開發者的所有行業傑克是一個次優的發展戰略的位置更好。




大多數人都錯過了重要的一點:在大多數情況下,你是顯著更高效的LINQ比SQL查詢時。我寫了一篇文章為什麼會這樣。

當我設置了LINQPad挑戰,我不是在開玩笑:我做我的幾乎所有即席查詢的LINQ,因為大多數查詢可以比SQL更快速,可靠地在LINQ寫的。我還設計並使用LINQ to SQL大型企業應用工作,在生產力的重大收益。這不是“架構太空人”的東西-的LINQ to SQL是一個高效和實用技術,推動這個非常網站

LINQ的最大障礙沒有正確的了解它。我已經看到了可怕的是這麼多的LINQ查詢音譯 SQL查詢來支持這一行動。如果您只使用SQL的知識寫LINQ查詢,最終的結果只能是相同的-或者更糟-比SQL。




我認為他們所需要的真正解決方案更像SQL文字。 VB.Net 9.0支持XML Literals ,它允許您在代碼中正確編寫XML,並確保驗證它並符合DTD。 一個類似的好功能是SQL文字,它允許你在你的.Net代碼中編寫內聯SQL代碼,並由IDE進行驗證。 需要有某種插件體系結構來驗證數據庫的信息,但這可以很容易地寫入流行的數據庫引擎。 這將提供我認為是真正的解決方案,解決他們正在試圖解決的問題,而不訴諸次優解決方案。