代码之家  ›  专栏  ›  技术社区  ›  Mark Brittingham

LinqtoSQL没有抓住要点吗?ORM制图器(亚音速等)不是次优解决方案吗?

  •  69
  • Mark Brittingham  · 技术社区  · 16 年前

    我想让社区了解我对Linq到Sql和其他ORM映射程序的一些想法。

    我喜欢Linq to Sql,喜欢用您的本地开发语言表达数据访问逻辑(或CRUD操作),而不必处理C#和Sql之间的“阻抗不匹配”。例如,要为业务层返回与ObjectDataSource兼容的事件实例列表,我们使用:

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

    如果要使用旧的SQL-to-C#构造实现此功能,我必须创建一个命令类,添加EventID参数(使用字符串描述“@EventID”参数),将SQL查询字符串添加到命令类,执行命令,然后使用(强制类型)nwReader[“FieldName”]提取每个返回的字段值并将其分配给我的EventData类的新创建实例的成员(恶心)。

    所以 这就是为什么人们喜欢Linq/亚音速/等等,我也同意。

    然而,从更大的角度来看,我看到了一些错误的事情。我的感觉是,微软也看到了一些错误,这就是为什么他们是错误的 killing Linq to SQL 并试图将人们从Linq转移到实体。只是,我认为微软是 在一个糟糕的赌注上加倍下注。

    那么,怎么了?

    architecture astronauts ,尤其是在微软,他们看到了Linq to Sql并意识到它不是一个真正的数据管理工具:仍然有许多事情在C#中不容易做到,他们的目标是 修好它。 revolutionary Linq的性质,甚至 LinqPad challenge .

    那个 它假设SQL是问题所在。也就是说,为了减少轻微的不适(SQL和Cα之间的阻抗不匹配),微软提出了等效的太空服(完全隔离),当一个创可贴(LINQ-SQL或类似的东西)会做得很好。

    就我所见,开发人员非常聪明,能够掌握关系模型,然后在他们的开发工作中智能地应用它。事实上,我会更进一步,说Linq到SQL、亚音速等等都是 已经太复杂了: 必须 掌握了SQL和关系模型,我们现在面临着学习 查询/CRUD语言。更糟糕的是,Linq通常很难测试(您没有查询窗口),将我们从实际工作中移除一层(它生成SQL),并且(最多)对SQL构造的支持非常笨拙,例如日期处理(例如DateDiff)、“拥有”甚至“分组依据”。

    替代方案是什么?就我个人而言,我不需要一个不同的数据访问模型,比如Linq到实体。我更喜欢在VisualStudio中弹出一个窗口,输入并验证我的SQL,然后按下按钮生成或补充一个C#类来封装调用。既然您已经了解SQL,您不希望只输入以下内容:

    Select EventID, Title From Events Where Location=@Location
    

    最终得到一个EventData类,该类A)包含作为属性的EventID和Title字段,B)具有一个工厂方法,该工厂方法将“Location”字符串作为参数,并生成一个列表<EventData>?您必须仔细考虑对象模型(上面的示例显然没有涉及到这一点),但是仍然使用SQL同时消除阻抗不匹配的基本方法对我很有吸引力。

    问题是:我错了吗?Microsoft是否应该重写SQL基础结构,这样您就不必再学习SQL/关系数据管理了? 可以 他们用这种方式重写SQL基础结构?或者,您认为在SQL之上设置一个非常薄的层来消除设置参数和访问数据字段的痛苦就足够了吗?

    我想把两个链接推广到顶端,因为我认为它们抓住了我所追求的重要方面。首先,CodeMonkey指出了一篇题为 "The Vietnam of Computer Science." 这需要一段时间来开始,但这是一本非常有趣的书。其次,安斯格里指出乔尔·斯波尔斯基的一首更为突出的作品: The Law of Leaky Abstractions

    更新2:我已经给了ocdecio“答案”,尽管这里有很多很好的答案,选择“正确”的答案纯粹是主观的。在这种情况下,他的回答与我认为的在当前技术状态下的最佳实践相符。然而,这是一个我完全期待发展的领域,所以事情很可能会发生变化。我要感谢每一个做出贡献的人,我已经投票给了每一个我认为给出了深思熟虑的答案的人。

    24 回复  |  直到 15 年前
        1
  •  45
  •   SquareCog    16 年前

    让我先说一句,我是一个彻头彻尾的人。

    希望 了解SQL。他们可以写,他们可以设计桌子,但这让他们觉得恶心。当必要的查询不仅仅是简单的连接时,他们往往会做一些愚蠢的事情。不是因为开发人员很愚蠢,而是因为他们不会被打扰。他们 生活在一个他们只需要处理一个概念空间的世界里;从对象到表再到表是一种上下文切换,这是他们不愿意付出的代价。

    这并不意味着他们是坏的,或是错的;这意味着有改进的机会。如果您的客户(在本例中,是使用您的框架的开发人员)不喜欢SQL和表,那么为他们提供一个抽象层,让他们不必处理底层的混乱。

    正是这种逻辑使得垃圾收集/自动内存管理大受欢迎。是的,开发者可以处理它;是的,他们可以编写更好优化的代码;但不必处理这些问题会让他们更快乐、更有效率。

        2
  •  36
  •   Jim Anderson    16 年前

        3
  •  18
  •   Otávio Décio    16 年前

    我对我所拥有的感到高兴,没有发现任何值得放弃的东西。

        4
  •  12
  •   Frederik Gheysels    16 年前

    它使您能够将更多的注意力放在您的问题域上,因为您需要花费更少的时间编写枯燥的CRUDSQL查询。另一方面,如果您使用的是良好的OR/M,那么如果有必要,这个OR/M应该使您能够编写SQL查询。

    如果使用得当,OR/M可能是一个强大的工具;它可以处理延迟加载、多态查询/关联。。。

    使用OR/M也不意味着作为开发人员,您不应该了解SQL。相反,伊姆霍是正确的。

    我还必须承认,我写这篇文章的目的是为了纪念NHibernate。这是我使用atm的OR/M,我还没有使用LINQtoSQL或LINQtoEntities(至今)。

        5
  •  10
  •   Trevor Abell    16 年前

    Linq的设计和LINQtoEntities框架当然可以用作orm工具,但重要的是它将被用作查询任何数据源的通用api,而不仅仅是RDBMS。

    我记得读到过这样一篇文章,linq显然是为了SQL而设计的,它是一种用于任何数据存储的查询语言。您可以为SQL编写linq查询,但理论上也可以编写针对ldap、文件系统、exchange、web服务的linq查询。这些程序不能使用SQL。

    您还需要为几乎每个数据存储学习不同的API。Linq为每个人提供了一个创建数据访问API的共同目标。

    http://laribee.com/blog/2007/03/17/linq-to-entities-vs-nhibernate/

        6
  •  9
  •   Cristian Libardo    16 年前

    你应该停止担心,学会爱这个世界。这样的抽象概念将有助于我们专注于技能并在该领域取得进步。

    仍然有很大的空间可以利用您已经掌握的功能技能,并将其应用于应用程序层。这实际上是LINQtoSQL相对于其他ORM的优势之一。

    可能不太明显的是,ORM提供了许多非常好的特性。标识映射有助于避免反复加载项,延迟加载有助于用较少的管道来表示域,工作单元有助于跟踪更改和优化数据库写入。

        7
  •  9
  •   dkretz    16 年前

    它不起作用。

    您只需学习如何进行相移:学习如何根据您要寻址的域对代码进行不同的思考。

        8
  •  7
  •   Community CDub    8 年前

    作为德米特里 pointed out ,开发人员不懂SQL。更准确地说,大多数人 SQL,但不要这样做 它肯定不喜欢,所以他们倾向于寻找魔弹,对Linq这样的东西产生需求,使他们产生错觉(嗯,抽象),认为他们使用的东西与他们喜爱的类没有任何不同。

    那太糟糕了,因为 the law of leaky abstractions 这是真的。

    有些ORM解决方案确实很好(例如JPA/Hibernate),这不是因为使用它们您不必担心SQL。事实上,要有效地使用JPA,您需要对DB有非常深入的了解,尤其是查询能力。好的一点是他们 让机器做镗孔工作

    我认为Linq到SQL并不能解决真正的问题。这是另一种展示,仅此而已。它可能很好,尽管它使已经很复杂的语言过于复杂。另一方面,LINQtoObjects是一个非常有趣的概念,因为它是一种查询集合的sql。

        9
  •  6
  •   DOK    16 年前

    历史观点。

    如果微软有一个很好的故事,他们正在复兴这些其他语言中的一种,或者已经发明了一种值得添加的语言,那么我认为我们最好听一听。但到目前为止,我所看到的只是另一个“一环统治一切”。

    SQL背后有大量的思想和严格性,以及大量经时间证明的耐久性。微软有一定的历史,相信他们公认的顶级开发组织能够超越我们其他人,包括我们集体的制度记忆。这种方式似乎并不常见。只要我们与关系数据存储绑定在一起,我们就应该对超集抽象范式三思而后行,超集抽象范式让我们远离裸机,并承诺具有相同或更好的性能。

        10
  •  5
  •   Isaac Dealey    16 年前

    作为一个ORM项目的作者,我不得不承认我对这样一个问题的回答有点偏颇。在阅读问题之前,我已经对答案有了一些自己的想法,所以我已经有点确定了。

    我要说的是,我开发ORM的原因并不是因为SQL和命令式编程之间的“阻抗不匹配”,而是完全为了成为数据库平台不可知论者。前一个问题是必须编写更多代码来管理持久性,如果您只与一家数据库供应商合作,这是一个很容易解决的小障碍。成为数据库平台不可知论者是一个更具挑战性的问题,imo对您企业的盈利能力有更大的影响,假设您和我一样计划向其他人销售软件(而不仅仅是在内部使用)。

    几年前,当我开始使用ORM工具时,这个概念在我的首选语言中是不切实际的,与我交谈的大多数人都不明白我为什么要做这件事,社区中一些受人尊敬的声音甚至在商业杂志上发表文章,说我已经做的事情不仅是不可能的,而且是不可取的。我们给出了一些相同的原因——它太复杂,限制性强,增加了开销。今天,同一个社区至少有三种流行的数据库抽象工具(尽管关于术语ORM的定义存在一些争论)。我之所以提到这一点,是因为当我开始研究这些工具时,最初的反对意见比现在更重要。在这几年中,硬件和软件的底层技术发生了变化,使这些工具从长远来看更加实用。我的倾向是尝试从长远的角度看待软件,并致力于可能还不太实用但很快就会实用的解决方案。因此,考虑到我不会把LINQtoEntities算作解决某些问题的好方法。

    abstraction inversion

    因此,我想我的答案是这样的:如果你的问题是钉子,就用锤子;如果你的问题是螺丝,就用螺丝刀。

        11
  •  5
  •   kanad kanad    16 年前

    Dmitry关于开发人员不喜欢SQL的说法可能有很多道理,但解决方案不仅仅是ORM。解决方案是雇用一名开发DBA作为开发团队的一部分。在我的公司,我的.net开发团队有一位优秀的Oracle DBA,他绝对不做任何生产DBA工作。他在我们团队中的角色是数据建模、物理数据库设计、创建存储过程、数据分析等。他是我们数据库方面如此干净和高效的原因。我们所有的数据库访问都是通过存储过程进行的。

    http://www.simple-talk.com/sql/database-administration/what-use-is-a-development-dba/

        12
  •  4
  •   codemonkey    16 年前

    我做数据库和分布式应用程序编程(web和编译),我觉得花时间开发基于存储过程的数据访问层是值得的。就我个人而言,我更喜欢在开发过程的早期进行数据建模并确定所需的过程。。。似乎有助于发现设计/接口逻辑/结构问题。

    我不太喜欢内联数据库编程(不管sql代码是手工生成的还是机器生成的)。我相信数据库是一个人的应用程序的基础,并且花时间来手工编码存储的进程是值得的。

    也就是说,我对OODBMS的概念很感兴趣,并希望有一天我能在生产环境中进行一些工作。

        13
  •  4
  •   Cade Roux    16 年前

    如果您让对象模型和ORM来指定您的数据模型,那么最终将得到一个糟糕的数据模型,它没有被规范化和/或包含来自对象模型的工件。

    1张桌子=1节课是个坏主意。

    首先,您永远不会拥有表示多对多或多对一链接表的类。它们对应于对象模型中的子集合-链接本身不是对象。

    如果将数据库视为表,只需将对象保存在行中(一种常见的方法),并让应用程序直接访问表,那么就放弃了定义数据库可用于保护其外围的数据库服务接口层的所有好处。

    ORM有它的位置,但是如果您使用它们只是按照对象模型中的设计来持久化对象,那么您的数据库将不会是关系数据库,也不能作为一个数据库用于ETL、报告、重构等目的。

        14
  •  3
  •   JeeBee    16 年前

    我认为这些事情背后的逻辑是,与系统其他部分的开销相比,在框架层构建和运行SQL语句的开销是微不足道的(例如,HTTP请求往返时间要长几个数量级)。

    我不认为“不需要知道SQL”是一个因素。任何优秀的开发人员在开发过程中都需要了解SQL。数据库抽象层的思想是消除为数据库查询生成样板代码的工作。

    事实上,在我们的Java系统中,我创建了一个代码生成器实用程序,它接受带注释的类并生成一个完整的CRUDAPI,并处理随着时间的推移所获得的所有奇怪的东西。创建模型并对其进行注释要比费力地编写DAO容易得多。扩大这样一个工具的规模,最终会得到LINQ、Hibernate或其他无数ORMDB解决方案。

        15
  •  3
  •   Community CDub    8 年前
        16
  •  3
  •   Kibbee    16 年前

    我认为他们需要的真正解决方案更像是SQL文本。VB.NET9.0支持 XML Literals ,它允许您在代码中正确编写XML,并确保它经过验证并符合DTD。一个类似的好特性是SQL文本,它允许您在.Net代码中编写内联SQL代码,并由IDE进行验证。需要某种插件体系结构来验证数据库中的信息,但对于流行的数据库引擎来说,这很容易编写。这将为他们试图解决的问题提供我认为真正的解决方案,而不诉诸次优解决方案。

        17
  •  3
  •   Mark Brittingham    16 年前

    用C#建模——不管数据模型多么复杂——永远都不是一个好主意,因为它需要多次“在线”检查数据和更新各种表格。虽然确实可以在Linq或其他ORM中处理存储过程, 我所需要的 是一个包装类,允许我使用标准C#参数调用存储过程。事实上,这对我来说是如此迫切的需要,以至于我用T-SQL编写了一个代码生成器来创建这样的包装器。

        18
  •  3
  •   Steven A. Lowe    16 年前

    我不喜欢当前的任何解决方案,但我更喜欢选择更多,而不是选择更少;-)

    看不见的 ,在后台处理(通过预处理器代码生成器),并由非常简单的更新、删除和查找方法和简单容器控制。

    我很想再次看到这一点(也许有些对象实体模型已经做得很好了),OCL(对象约束语言)是本机的多对象查询语言

        19
  •  2
  •   CodingWithSpike    16 年前

    理想的解决方案?绝对不是!然而,我认为这是更好地将应用程序与数据存储合并的过程中的一次迭代。毕竟,在大多数情况下,没有用任何语言编写的访问应用程序的数据库实际上是无用的。(您真的会安装oracle,并期望所有员工直接在SQLPlus中工作吗?)

    特别是对于.NET,我更希望看到的不是Linq,而是一种内置的方式,将类定义映射到底层数据源,再映射到底层数据存储,并让所有管道都正常工作。

    当然,这样的解决方案会带来性能、事务处理等方面的问题。

    也许编程语言和关系数据库的整个概念需要重新思考和调整?在其核心,它们是完全分离和脱节的实体。也许是时候抛弃“关系型sql感知数据库”并构建下一件事了,因为执行一行代码将直接对数据库进行操作。

        20
  •  1
  •   DonOctavioDelFlores    16 年前

    linq没有问题,但是那些使用它而忽略“幕后”发生的事情的人

    我还是更喜欢用SQL把我的手弄脏。至少我确切地知道发生了什么事。

        21
  •  1
  •   fuzzbone    16 年前

    Ted Neward写了一篇关于他对这个主题的看法的伟大文章——ORM是计算机科学的“越南”。。。

    http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx

        22
  •  1
  •   Community CDub    4 年前

    生产率显著提高 在LINQ中查询时,比在SQL中查询时更有效。我已经 written an article 为什么会这样。

    当我设置LINQPad挑战时,我不是在开玩笑:我几乎所有的临时查询都是在LINQ中进行的,因为大多数查询都可以在LINQ中比在SQL中编写得更快、更可靠。我还使用LINQtoSQL设计和开发了大型业务应用程序,并看到了生产力的重大提高。这不是“架构宇航员”的东西——LINQ到SQL是一种高效实用的技术,可以 drives this very site .

    LINQ最大的障碍是没有正确地学习它。我见过太多可怕的LINQ查询 音译

        23
  •  1
  •   devuxer    15 年前

    我刚刚发现了这个问题。我想现在已经差不多玩完了,但我还是要投入我的两分钱。。。

    我只想为不明显的事情编写代码。

    积垢代码是显而易见的。我不想写它。因此,ORMs是一个好主意。

    DataView 每次我想分类或过滤一些东西。LINQ使我能够用C#中的数据做我想做的所有事情,而不必弄清楚如何在SQL和C#之间分配工作。

    因此,是的,ORMs、LINQ和其他新兴技术都是次优解决方案,但它们不会错过重点,也不会永远是次优的。

        24
  •  0
  •   Community CDub    8 年前

    here ,但它告诉我还有-1836个字符。S.O.noob,如果我做错了,我道歉。


    在18世纪,有闲的绅士曾学习科学。当时,整个科学并不是一门大学科,一个相当聪明的人不可能完全理解它。我的意思是,一个博学的人可以理解当时科学思想的全部。

    随着时间的推移,数百个新的科学领域被发现,每一个领域的研究都达到了现在很少有人能够理解一个完整的科学领域的整体的程度。

    编程也是如此。

    如今,编程语言领域已经足够大,发展速度也足够快,开发人员完全了解自己的专业语言是可以合理预期的。对于一个熟练的程序员来说,也需要了解整个数据库领域,包括数据库设计、原生SQL的细微差别、它如何在不同的数据库上运行以及这些数据库的管理,这可能要求有点高。

    我认为,这里的一些响应者正在掩饰开发大型高性能企业级数据库的复杂性,知道“少量SQL语句”肯定不能解决这一问题。这就是为什么大多数大型软件公司都有专门的数据库开发团队。正如Stroustrup所说,“分而治之”是有效处理开发和管理大型软件项目所固有的复杂性的唯一方法。

    开发人员不喜欢使用SQL,不是因为他们懒惰,也不是因为它让他们觉得“讨厌”。他们不喜欢使用SQL,因为他们很聪明。他们比任何人都清楚,只有专门研究SQL的人才能提供最高质量的数据库功能,而让他们成为“各行各业的高手”的开发人员是一种次优的开发策略。