难道 Linq to SQL 没有抓住要点吗? ORM 映射器(SubSonic 等)不是次优解决方案吗?

2024-05-07

我希望社区能够了解我对 Linq to Sql 和其他 ORM 映射器的一些想法。

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

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

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

So, that这就是人们喜欢 Linq/SubSonic/etc 的原因。并且我同意。

然而,从更大的角度来看,我发现了一些错误的事情。我的感觉是微软也看到了一些问题,这就是为什么他们杀死 Linq to SQL http://codebetter.com/blogs/david.hayden/archive/2008/10/31/linq-to-sql-is-dead-read-between-the-lines.aspx并试图将人们转移到 Linq to Entities。只是,我认为微软在一个错误的赌注上加倍下注。

那么,到底出了什么问题呢?

问题是有建筑宇航员 http://www.joelonsoftware.com/articles/fog0000000018.html尤其是在 Microsoft,他们研究了 Linq to Sql 并意识到它不是一个真正的数据管理工具:仍然有很多事情在 C# 中无法轻松轻松地完成,他们的目标是fix it.您可以在 Linq to Entities 背后的雄心壮志中看到这一点,以及关于革命性的 http://blogs.msdn.com/adioltean/archive/2005/09/13/465471.aspxLinq 的本质,甚至LinqPad 挑战 http://www.linqpad.net/Challenge.aspx.

问题是that是它假设 SQL 是问题所在。也就是说,为了减少轻微的不适(SQL 和 C# 之间的阻抗不匹配),微软提出了相当于宇航服(完全隔离)的方案,而创可贴(Linq to SQL 或类似的东西)就可以了。

据我所知,开发人员非常聪明,能够掌握关系模型,然后在开发工作中明智地应用它。事实上,我会更进一步说 Linq to SQL、SubSonic 等是已经太复杂了:学习曲线与掌握 SQL 本身没有太大区别。因为在可预见的未来,开发商must掌握了SQL和关系模型,我们现在面临着学习two查询/CRUD 语言。更糟糕的是,Linq 通常很难测试(您没有查询窗口),使我们远离了我们正在做的实际工作(它生成 SQL),并且对 SQL 结构的支持非常笨拙(最多),例如日期处理(例如 DateDiff)、“Having”甚至“Group By”。

还有什么选择呢?就我个人而言,我不需要像 Linq to Entities 这样的不同模型来进行数据访问。我更愿意在 Visual Studio 中弹出一个窗口,输入并验证我的 SQL,然后按一个按钮来生成或补充 C# 类来封装调用。既然您已经了解 SQL,您是否愿意输入如下内容:

Select EventID, Title From Events Where Location=@Location

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

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

Update我想将两个链接提升到顶部,因为我认为它们抓住了我所追求的重要方面。首先,CodeMonkey指出一篇文章,题为“计算机科学的越南”。 http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx开始需要一段时间,但读起来非常有趣。其次,AnSGri 指出了乔尔·斯波尔斯基 (Joel Spolsky) 更著名的作品之一:抽象泄漏法则 http://www.joelonsoftware.com/articles/LeakyAbstractions.html。它不完全是主题,但很接近并且是一本很好的读物。

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


首先我要说的是,我是一个十足的数据库专家。

作为一种严重的过度概括: 开发人员不懂SQL。开发商确实不want了解 SQL。他们可以写它,他们可以设计表格,但这让他们感到恶心。当必要的查询不仅仅是简单的连接时,他们往往会做愚蠢的事情。并不是因为开发人员愚蠢——而是因为他们不愿意被打扰。他们like生活在一个他们只需要处理一个概念空间的世界;从对象移动到表并返回是一种上下文切换,他们不喜欢为此付出代价。

这并不意味着它们是坏的或错误的;而是意味着它们是错误的。这意味着有改进的机会。如果您的客户(在本例中是使用您的框架的开发人员)不喜欢 SQL 和表,请为他们提供一个抽象层,让他们无需处理底层的混乱情况即可摆脱困境。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

难道 Linq to SQL 没有抓住要点吗? ORM 映射器(SubSonic 等)不是次优解决方案吗? 的相关文章

  • 使用 java 中的准备好的语句插入自定义 SQL 类型

    我有一些自定义类型 它们基本上都是枚举 以下是它们的外观示例 CREATE TYPE card suit AS ENUM spades clubs hearts diamonds 我在 Java 中有一些准备好的语句 看起来像这样 Setu
  • 如何使 cx-oracle 将查询结果绑定到字典而不是元组?

    这是我的代码 我想找到一种方法将查询结果作为字典列表而不是元组列表返回 看起来 cx oracle 通过部分文档讨论 绑定 来支持这一点 虽然我不知道它是如何工作的 def connect dsn cx Oracle makedsn hos
  • 找到帖子链接、每个标签对应的相关标签并在用户级别进行回答

    继续我之前的question https stackoverflow com questions 60967044 retrieve count of total no of answers corresponding to each ta
  • 无法从 CursorWindow 读取第 0 行,第 -1 列?

    我在使用数据库时遇到问题 当我运行 SQLView java 时 出现致命异常 java lang RuntimeException Unable to start activity ComponentInfo com jacob eind
  • plpgsql 中的伪加密() 函数采用 bigint

    我正在开发一个生成随机 ID 的系统 如答案 2 所示here https stackoverflow com questions 12575022 generating an instagram or youtube like ungue
  • Django:ImageField 需要文件路径还是实际的图像对象?

    Running Windows 7 Python 3 3 Django 1 6 我对如何将图像存储为 Django 数据库中表的一部分感到困惑 有一个领域叫做ImageField 这是Docs https docs djangoprojec
  • 使用连接字段的 SQL JOIN

    我有两个表 Table1 包含一列 该列构成 Table2 中列的部分值 例如 表1 XName 123456 表2 ZName ABC 123456 我需要创建一个与这些匹配的 JOIN 但是使用 MS SQL 2008 我在完成这项工作
  • Django 视图中的原始 SQL 查询

    我将如何使用原始 SQL 执行以下操作views py from app models import Picture def results request all Picture objects all yes Picture objec
  • FROM 子句中子查询末尾随机字母的含义 - SQL

    我终于成功将两个sql sum查询的结果求和了 这家伙迈出了一小步 我的问题与代码中的最后一个字符 Z 有关 SELECT SUM hr FROM SELECT SUM amount AS hr FROM Try again dbo tue
  • INSERT INTO ... SELECT ... 是否始终按序号位置匹配字段?

    我的测试似乎证实了这一点 INSERT INTO a x y SELECT y x FROM b maps b y to a x 即字段仅按顺序位置匹配 而不按名称匹配 情况总是如此吗 即 我可以依赖这种行为吗 很遗憾 文档 http ms
  • 如何使用 Linq to Sql 修剪值?

    在数据库中 我有一个名为 联系人 的表 名字和其他此类字符串字段设计为使用 Char 数据类型 不是我的数据库设计 我的对象 Contact 映射到属性中的字符串类型 如果我想做一个简单的测试 通过 id 检索 Contact 对象 我会这
  • 如何获取数字列的确切类型,包括。规模和精度?

    有没有办法知道列中列的确切类型DataTable 现在我正在这样做 DataTable st dataReader GetSchemaTable foreach DataColumn col in st Columns var type c
  • Presto 数组包含一个喜欢某种模式的元素

    例如 我的表中的一列是一个数组 我想检查该列是否包含包含子字符串 denied 的元素 因此 在中午 12 00 拒绝 被管理员拒绝 等元素都将计数 我相信我将不得不使用 like 来识别模式 这个sql该怎么写呢 使用急板数组函数 htt
  • 连接查询或子查询

    开发人员何时使用联接而不是子查询是否有经验规则 或者它们是否相同 第一个原则是 准确地陈述查询 第二个原则是 简单明了地陈述查询 这是你通常做出选择的地方 第三个是 陈述查询 以便它能够有效地处理 如果它是一个具有良好查询处理器的数据库管理
  • 从基本控制器继承 LINQ-to-SQL 数据上下文

    我的基本控制器类 BaseController 由面向公众的控制器继承 用于使用 LINQ to SQL 访问请求之间的共享数据上下文 我是否可以通过将数据存储在中来以高效且安全的方式访问我的数据上下文HttpContext Current
  • 使用临时表替换 WHERE IN 子句

    我让用户输入我需要在表中查询的值列表 该列表可能非常大 并且长度在编译时未知 而不是使用WHERE IN 我认为使用临时表并对其执行联接会更有效 我在另一个SO问题中读到了这个建议 目前找不到它 但会在找到时进行编辑 要点是这样的 CREA
  • 在自定义条件下清理 SQL

    我需要创建一个简单的搜索 但我无法使用 Sphinx 这是我写的 keywords input split s queries keywords each do keyword queries lt lt sanitize sql for
  • ORACLE 在立即执行中批处理 DDL 语句

    我正在尝试在一个 Execute Immediate 语句中运行多个 ddl 语句 我认为这会很简单 但看来我错了 想法是这样的 declare v cnt number begin select count into v cnt from
  • 帮助将二进制图像数据从 SQL Server 读取到 PHP 中

    我似乎无法找到将二进制数据从 SQL 服务器读取到 PHP 的方法 我正在开发一个项目 需要能够将图像直接存储在 SQL 表中 而不是文件系统上 目前 我一直在使用这样的查询 插入 myTable 文档 选择 从 OPENROWSET BU
  • Postgresql 和 jsonb - 将键/值插入多级数组

    非常类似于这个帖子 https stackoverflow com questions 58959678 postgresql add key to each objects of an jsonb array 但我很难适应他们的解决方案

随机推荐

  • onDataChanged() 在 Android Wear 上未被调用

    我试图使用数据项将一些字符串发送到我的穿戴设备 但我的穿戴设备似乎从未收到任何信号 因为 onDataChanged 从未被调用 我什至设置了一个时间戳 以确保每次发送数据时始终不同 有没有特定的方法我必须将应用程序安装到两台设备上才能使其
  • 从Python中的URL中提取域[重复]

    这个问题在这里已经有答案了 我有一个像这样的网址 http abc hostname com somethings anything 我想得到 hostname com 我可以使用什么模块来完成此任务 我想在python2中使用相同的模块和
  • 从另一个文件执行按钮命令?

    我已经开始开发一个 GUI 系统 在该系统中 我需要从一个文件导入一个函数 以便在按下按钮时在主文件中执行 但每次运行它时 我都会得到 AttributeError partially initialized module Two has
  • 在 Docker Compose 中更改 postgres 容器服务器端口

    我正在尝试使用 Docker compose 在远程服务器上部署第二个数据库容器 该 postgresql 服务器在端口 5433 上运行 而不是第一个 postgresql 容器使用的端口 5432 当我设置应用程序时 我收到以下错误输出
  • 获取没有特定祖先 xml xpath 的节点

    我想要 xpath 它获取没有祖先的节点 它是特定节点的第一个后代 假设我们有这样的 xml 文档 a b This node b a
  • CKEditor - 内联:以禁用模式显示

    我正在尝试在内联模式下使用 CKEditor 如下所示 var div div content CKEDITOR disableAutoInline true CKEDITOR inline div 0 单击 div 时 将显示 CKEdi
  • 在android中重叠屏幕

    在下面的布局中 我有一个名为扫描设备的文本视图 其中显示设备名称 但我的设备列表显示在屏幕上方 任何人都可以帮助我如何滚动视图应该在设备列表内 滚动屏幕时 它显示设备列表 但它显示在屏幕上方 想要显示在屏幕内
  • Windows 控制台“ESC[2J”并没有真正“清除”屏幕

    我知道这类问题经常被问到 但我认为这个问题有点不同 需要被问到 新的 Windows 控制台支持 ANSI VT100 控制代码 ANSI VT100 控制代码 http www termsys demon co uk vtansi htm
  • 错误LNK2001:无法解析的外部符号公共:静态类[重复]

    这个问题在这里已经有答案了 我不明白为什么我会收到这个错误 任何人都可以伸出援手吗 我需要在头文件中声明VideoCapture捕获并在Video cpp中调用它 Video h class Video public static Vide
  • mongodb c# 选择特定字段

    需要一些帮助来创建generic按名称选择字段的方法 像这样的东西 T GetDocField
  • 如何防止模块被导入两次?

    在编写python模块时 有没有办法防止它被客户端代码导入两次 就像 c c 头文件一样 ifndef XXX define XXX endif 非常感谢 Python 模块不会被多次导入 仅运行两次 import 不会重新加载模块 如果你
  • Xcode 中的“使用不间断空格 (U+00A0) 代替常规空格”警告

    When typing a space character in Xcode a warning appears sometimes 使用不间断空格 U 00A0 代替常规空格 早期的 Xcode 版本显示以下消息 将 Unicode 字符
  • 如何获取表单的onSubmit事件?

    我想知道如何抢onsubmit表单中的事件来进行一些表单验证 因为我无权直接访问它 我正在编写一个用于评论的 WordPress 插件 因此无法直接访问表单标签或提交按钮 我在尝试为我的插件执行此操作时感到非常沮丧 因此我在下面编写了一个
  • 如何选择集合的第一个元素作为查询的列

    表 t 有两列 a 和 b a是整数 b是集合 我想为每一行选择 a 和集合 b 的第一个值 我试过了 但没用 WITH s a b AS SELECT 1 ff FROM DUAL UNION ALL SELECT 1 ee FROM D
  • 如何将十进制整数转换为十六进制整数? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions cout lt
  • 如何运行 Abaqus 宏 (.py) 脚本

    我是Python新手 我使用 Abaqus 宏管理器生成了一个宏 它是一个 py 脚本 我意识到该脚本仅在从 Abaqus 管理器运行时才有效 并且不能自行运行 请有人知道如何修改这个脚本 以便我可以在不使用 Abaqus 的情况下运行它
  • 如何绘制两个 ggplot 密度分布之间的差异?

    我想使用 ggplot2 来说明两个相似密度分布之间的差异 这是我拥有的数据类型的玩具示例 library ggplot2 Make toy data n sp lt 100000 n dup lt 50000 D lt data fram
  • 退出失败设置错误代码

    我有一个 C Windows 程序无法设置退出代码 该程序非常复杂 我目前无法通过简单的测试用例重现该程序 我确实知道该程序调用exit 1 因为我在那一行有一个断点 在我跨过它之后 调试器 VS2010 立即打印The program p
  • 使用 Rails 自动登录?

    我正在尝试使用 Rails 的 Restful Authentication 插件建立一个简单的身份验证系统 我只是想知道它是如何工作的 b c 我似乎无法弄清楚 cookie 的要求是什么 以及如何做到这一点浏览器始终会记住您 6 个多月
  • 难道 Linq to SQL 没有抓住要点吗? ORM 映射器(SubSonic 等)不是次优解决方案吗?

    我希望社区能够了解我对 Linq to Sql 和其他 ORM 映射器的一些想法 我喜欢 Linq to Sql 以及用本机开发语言表达数据访问逻辑 或一般的 CRUD 操作 的想法 而不必处理 C 和 SQL 之间的 阻抗不匹配 例如 要