Linq to SQL不會錯過這一點? 是不是ORM映射器(SubSonic等)次優解決方案?


11 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 to SQL並試圖將人員轉移到Linq to Entities。 只是,我認為微軟在糟糕的賭注上加倍了。

那麼,什麼是錯的?

問題是有架構的宇航員 ,特別是微軟的宇航員 ,他們看Linq to Sql並意識到它不是一個真正的數據管理工具:在C#中仍然有很多事情你不能輕鬆完成,他們的目標是修復它。 您看到這一點表現在Linq to Entities背後的雄心壯志,關於Linq revolutionary性質的博客文章以及LinqPad挑戰

問題在於它假設SQL是問題所在。 也就是說,為了減少輕微的不適感(SQL和C#之間的阻抗不匹配),Microsoft提出了相當於一個太空服(完全隔離),當一個創可貼(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的其中一個更突出的部分: 洩漏抽象定律 。 它不完全是主題,但它很接近,是一個偉大的閱讀。

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




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

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

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

我也傾向於選擇更多的選擇而不是更少的選擇。 所以,雖然我可能支持開發LINQ to Entities的想法,但我不太傾向於支持將LINQ to SQL殺死,因為LINQ to Entities已經可用。 對像對做什麼對像很有幫助,這是毫無疑問的......在我(又偏向)的觀點中,出現了一個問題,即人們將任何給定的工具或軟件範例看作是“魔法子彈”,並且希望堅持一切必須這樣。 眾所周知,關係數據庫非常擅長處理某些其他任務,報告就是一個很好的例子。 所以在我看來,這是一種強烈的自責,堅持一切都必須是實體,因為那樣你就會迫使自己使用低效的工具來完成這項工作。 因此,就報告而言,擺脫LINQ to SQL和僅使用LINQ to Entities至少在表面上聽起來像抽象反轉反模式。

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




Most people have missed an essential point: in most cases, you are significantly more productive when querying in LINQ than in SQL. I've written an article on why this is so.

When I set the LINQPad Challenge, I wasn't joking: I do nearly all of my ad-hoc querying in LINQ because most queries can be written more quickly and reliably in LINQ than in SQL. I've also designed and worked on large business applications using LINQ to SQL and seen a major gains in productivity. This is not "architecture astronaut" stuff - LINQ to SQL is a productive and practical technology that drives this very site .

The biggest hindrance with LINQ is failing to properly learn it. I've seen so many LINQ queries that are horrible transliterations of SQL queries to back this up. If you write LINQ queries using only your knowledge of SQL, the end result can only be the same - or worse - than SQL.




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

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

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

我認為,Linq to SQL並不能解決真正的問題。 這是一種其他的演示,僅此而已。 它可能是好的,但它會使已經很複雜的語言複雜化。 另一方面,Linq to Objects是一個非常有趣的概念,因為它是一種查詢集合的sql。




I don't like any of the current solutions - but i prefer more choices over less choices ;-)

i used an OODBMS in a project long ago that was the closest to getting it right (unfortunatley the product had some heinous bugs and terrible tech support) - object persistence was largely invisible , handled behind the scenes (via preprocessor code-generator) and controlled by very simple Update, Delete, and Find methods and simple containers.

I'd love to see this (and perhaps some object-entity model does this well already) again, with OCL (Object Constraint Language) as the native multi-object query language




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

仍然有足夠的空間利用您已獲得的功能技能並將其應用到應用程序層。 事實上,這是LINQ to SQL優於其他ORM的強項之一。

我只能同意其他許多意見。 您保存的時間,您可以專注於改進您的域模型並創建更好的應用程序。 而且,一旦你確定了瓶頸,用它來創建優化的SQL。

ORM帶有許多非常好的功能,可能不會立即顯而易見。 有助於避免一次又一次加載項目的身份映射,延遲加載可幫助您用較少的管道表達域,並且工作單元可幫助您跟踪更改並優化數據庫寫入。




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

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

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

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




there´s no problem with linq, but with those who use it and ignore what happens "behind the scenes"

I still prefer to get my hands dirty with SQL. At least i´ll know exatcly whats happening.




我認為他們需要的真正解決方案更像SQL文字。 VB.Net 9.0支持XML Literals ,它允許您在代碼中正確編寫XML,並確保驗證它並符合DTD。 一個類似的好功能是SQL文字,它允許您在.Net代碼中編寫內聯SQL代碼,並由IDE進行驗證。 需要有某種插件體系結構來驗證數據庫中的信息,但這可以很容易地寫入流行的數據庫引擎。 This would provide what I think to be the real solution, to the problem they were trying to solve, without resorting to sub-optimal solutions.




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

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

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

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

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

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




恕我直言,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到實體(還)。




I wanted to write this as a reply to @SquareCog reply here , but it told me I had -1836 characters left. SO noob here so apologies if I've done this wrong.

In the 18th century gentleman of leisure used to study science. At that time science in its entirety was not such a large subject that a reasonably intelligent person couldn't understand it all. By which I mean a single learned fellow could understand the entirety of scientific thinking of the time.

As time has gone by hundreds of new fields of science have been discovered and each one researched to the point where these days very few people can even understand the entirety of a single complete field of science.

So it is with programming.

These days the programming language field is large enough and growing fast enough that it is as much as can be reasonably be expected of a developer to know the entirety of his own specialised languages(s). For a skilled coder to also be expected to understand the entirety of the database field too, including database design, the nuances of native SQL and how it operates on different databases and the administration of those databases too, is possibly asking a bit much.

I think some of the responders here are glossing over some of the complexities of developing a large performant enterprise level database, knowing a 'handful of SQL statements' most certainly does not cut it. Which is why most large software houses have dedicated teams of database developers. As Stroustrup says, 'Divide and conquer' is the only way to effectively deal with the complexity inherent in developing and managing large software projects.

開發人員不喜歡使用SQL,因為他們很懶,或者因為它讓他們覺得'icky'。他們不喜歡使用SQL,因為他們很聰明。他們比任何人都清楚,只有專門從事SQL工作的人才能提供最高質量的數據庫功能,並使他們能夠成為“所有行業的傑作”,這是一個次優的發展戰略。




Related