为什么人们使用linq来sql?

时间:2009-06-19 13:30:52

标签: linq linq-to-sql

考虑到前提:

  • 有称职的sql程序员 (相关 - 编写SQL查询不是问题)
  • 有称职的应用程序开发人员 (相关 - 有简单/强大/灵活的架构,用于处理连接和代码中的简单查询)

为什么人们使用linq来实现sql?

  • 每项交易都增加了开销
  • 中等复杂计算很可能会出现性能损失(数据库用于处理集和计算,并且有工程师团队正在进行优化 - 为什么要搞这个?)
  • 失去灵活性(如果您想添加另一个ui(非.NET应用程序)或访问方法,您必须将查询放回数据库或创建单独的数据访问层)
  • 由于没有对db进行写/更新/读取的集中控制而导致安全性下降(例如,记录已更改 - 如果允许应用程序使用linq to sql进行更新,则无法证明哪个应用程序已更改它或应用程序的哪个实例改变了它)

我一直看到关于linq到sql的问题,我想知道我是否遗漏了什么。

11 个答案:

答案 0 :(得分:41)

  

我一直看到关于linq到sql的问题,我想知道我是否遗漏了什么。

并不是说你错过了什么。这是你有大多数商店没有的东西:

  

有称职的sql程序员

此外,在您的商店中,那些称职的SQL程序员更喜欢编写sql。


以下是逐点回复:

  

每笔交易都增加了开销

一般都是如此。这可以通过在需要使用CompiledQuery运行许多(但不是全部!)场景之前翻译查询来避免。

  

对于中等复杂的计算,很可能会出现性能损失(数据库用于处理集和计算,并且工程师团队正在进行优化 - 为什么要搞这个?)

要么你正在编写linq,它被翻译成sql,然后从优化器生成一个计划 - 或者你的编写sql,优化器生成一个计划。在这两种情况下,你都在告诉机器你想要什么,它应该弄清楚如何去做。您是否建议使用查询提示破坏优化程序是一种好习惯?许多称职的sql程序员不同意这个建议。

  

失去灵活性(如果您想添加另一个ui(非.NET应用程序)或访问方法,您必须将查询放回数据库或创建单独的数据访问层)

很多使用linq的人已经是SOA了。 linq住在一项服务中。非.NET应用程序调用该服务。 Bada-bing bada-boom。

  

由于没有对db进行写/更新/读取的集中控制而导致安全性下降(例如,记录已更改 - 如果允许应用程序使用linq to sql进行更新,则无法证明哪个应用程序已更改它或应用程序的哪个实例改变了它)

这根本不是真的。您可以证明哪个应用程序已连接并发出sql命令的方式与证明哪个应用程序已连接并调用sproc一样。

答案 1 :(得分:29)

让我列举几点:

  1. 有些小型软件公司或中型公司在内部开发软件,而不是专注于获得许多应用程序开发人员,而不是聘请自由职业者数据库开发人员,甚至永久雇用他们。
  2. 在大多数情况下,由于要处理的数据量或流量较低,开销不是问题。此外,如果使用得当,LINQ to SQL的执行速度与大多数SQL查询+相关的.net代码一样快。
  3. 许多公司只是坚持使用Microsoft堆栈,他们只能享受集成。其他一些公司使用SOA开发并没有问题。其他人不会被迫选择LINQ-to-SQL,如果他们做出选择就是如何整合它的问题。没有人说过LINQ-to-SQL是一个银弹:)
  4. 我认为LINQ-to-SQL的安全性已经获得,因为我遇到了许多SQL查询,它们使用字符串连接等非转义数据并解释整个参数化查询的想法从未如此简单。此外,由于所有查询最终都会转换为SQL,除非您描述的跟踪问题是通过存储过程发生的,否则根本不会出现任何问题。
  5. 我也相信你的问题可以更普遍地提出来解决所有ORM而不仅仅是LINQ-to-SQL,而且我所说的大部分内容都适用。

答案 2 :(得分:14)

问题在于,某个地方很难有一个有能力的SQL开发人员喜欢编写SQL而不愿意做其他事情。我认为自己在SQL方面很有能力,我以前用存储过程或参数化查询做我所有的数据访问层。麻烦的是它需要很长时间而且很无聊。我宁愿编写出色的应用程序而不是搞乱数据访问层,这些层基本上有一个select,insert,update和delete SQL语句(或proc),每个数据对象重复几十次。

Linq-to-SQL消除了一些重复性。它有一个从数据库模式自动生成业务对象的工具,它为您提供了一个很好的集成查询语言,它是经过编译的时间类型验证并且在您的代码中(存储过程很难控制源代码控制)

我可以在Linq-to-sql中编写DAL的速度比使用普通SQL,存储过程或参数化查询快几倍。

如果你想保持使用存储过程,linq-to-sql和EF都支持使用存储过程进行所有数据访问,你只需要设置适当的映射。因此,如果需要,您仍然可以使用存储过程来记录详细信息并实现安全性。我们倾向于选择使用Windows身份验证,并使用它来限制对各个用户的每个表的访问,然后我们在表上有一堆触发器来跟踪详细信息以用于审计目的。

我将很快注意到的两件事情是,首先,实体框架似乎得到了MS的更多支持,我怀疑这将被视为未来的默认标准,而不是linq-to- SQL。其次,在.Net 3.5中,EF和linq-to-sql对n层断开连接的应用程序没有很好的支持。在这两种方法中,您都需要在断开连接的层中序列化数据上下文,或者手动分离并重新附加数据对象。这在.net 4.0中有很大的改进。根据您可以使用的版本,可以考虑一些事项。

答案 3 :(得分:9)

以同样的方式/精神存在的问题/答案:

我个人认为没有正确或错误的答案。这取决于你正在开发什么以及你如何开发它。如果你需要锐利的性能,有一个过于复杂的数据模型等...跳过抽象。如果您觉得抽象可以加快您的开发时间,例如在单个代码库中捕获所有应用程序逻辑的想法等等......使用它。

答案 4 :(得分:4)

对我来说,编写linq到sql代码比编写一堆存储过程花费的时间少得多。当设计没有完成时尤其如此,在这种情况下,我还不知道我想对C#对象做多少工作,以及我想在SQL中做多少工作。

所以,我可以跳过构建数据集,我没有点击单击点击添加查询,基本上,linq到sql意味着我可以在更短的时间内更改我的代码。

另外,作为Haskell的忠实粉丝,我可以用linq编写大量功能样式的代码到sql,它就可以了。

答案 5 :(得分:4)

我不是说这是一个理想的解决方案,甚至是一个很好的例子(这是对架构的高级别约束的结果,而不是我们必须从头开始选择的),但是......

我在一个应用程序上工作,其中代码与数据库完全隔离,除非通过一组暴露的存储过程。代码无法“知道”有关数据库模式的任何信息,除非从存储过程返回。

虽然这不是那么不寻常并且使用ADO或其他任何东西编写DAL并不困难,但我决定尝试使用Linq to Sql,即使它不会将其用于其真正的预期目的,不会使用大多数功能。事实证明这是一个伟大的决定。

我创建了Linq to Sql类,将存储过程从服务器资源管理器拖到设计器的右侧,然后......等等,没有。我已经完成了很多。

Linq为每个存储过程创建了强类型方法。对于返回数据行的proc,Linq自动为每行中的项创建一个类,并为它们返回List<generatedClass>。我把调用本身包装在一个轻量级的公共DAL类中,它做了一些验证和一些自动参数设置,我就完成了。我编写了一个业务对象类,并将动态生成的Linq类对象映射到业务对象(手动完成,但不难做或维护)。

该程序现在不受任何不影响存储过程签名的架构更改的影响。如果签名确实发生了变化,我们只需从设计中拖出旧的proc并将其拖回以重新生成代码。一些通过单元测试进行更改(通常不会高于公共DAL接口)并且已完成。 DAL上游的东西使用Linq to Objects技术来直接从存储的proc调用中选择,过滤和排序不正确格式的数据。

我们有一些优秀的DBA编写存储过程,而一个完全不同的组编写其他代码,所以也许这是为什么(以及如何)在您描述的场景中使用LINQ的一个很好的例子。

答案 6 :(得分:2)

与将SQL语句编写为字符串相比,一些方便的功能是调试器在查询中拾取sytax错误。错误,直到运行时才会被捡起来。

另外,我发现LINQ语句比SQL更容易阅读。

答案 7 :(得分:1)

可能是方便胜利的表现。如果你正在Facebook级别的超级性能编程,那么你可能会考虑每个时钟周期,但简单的事实是大多数应用程序不需要这种关注,并从代码维护和开发时间的效率中受益(10万承包商vs另一个$ erver)。

也就是说,有一种情况可以在极高规模的系统中从数据库框中外包尽可能多的查询处理,否则数据库就是瓶颈,你需要对该线进行分片或重新构建。昂贵的。

我认为公平地说,LINQ将在服务器和许多核心方面更好/更容易扩展,因为只要MS发布C#4.0,您的LINQ代码库将获得“免费”的m-core。

我确实看到了你的要点,并且作为一个非ASP.NET开发人员第一次开始一个www项目,我看不到80%的ASP.NET(主题,控件等) - 似乎我需要学习更多内容并编写代码而不是HTML本身! - 再次,我确信这一切都有充分的理由。

---我没有得到50分来评论我想要的帖子所以我在这里做了---

David B建议编写一些SQL是为了充分利用SQL Server,并且使用查询提示是转向机制。在SQL中可以通过许多不同的方式实现相同的任务,并且许多方法的性能提升为1000倍。我建议阅读Inside T-SQL Querying(Itzik Ben Gan)。 Itzik一遍又一遍地展示了如何重新考虑查询并使用新命令将逻辑读取有时从数千个缩小到不到10个。

答案 8 :(得分:0)

对于非常简单的查询,额外图层的开销会增加往返成本。对于普通“业务应用”场景中稍微复杂的查询,Linq-to-SQL表达式&gt; sql翻译魔术所做的优化通常可以节省很多。

例如,我最近将客户提供的1400+(!)行存储过程的1:1翻译到L2S。它不仅从1400行SQL到500行更易读,强类型和注释的代码。它也开始以平均约1500次读取而不是〜30k读取命中数据库。这是在我开始研究数据库端优化之前 - 保存是我可以100%归因于L2S消除可以在客户端评估的谓词的能力。

答案 9 :(得分:-2)

请在我之后重复(分钟3x)

  • 没有银弹

  • 我不会仅仅因为它来自msft

  • 的最新产品而使用技术
  • 我不会仅仅使用某些东西来获取我的简历

他们称职的SQL编程人员,任何体面的应用程序编程人员,尤其是LOB应用程序,都应该编写中间SQL。如果您不知道任何SQL并且正在编写LINQ to SQL,那么您将如何调试数据调用?您如何描述它们以修复瓶颈?

我们正在尝试使用LINQ to SQL,我认为它存在一些重大问题,例如:

  • 没有简单的方法可以将查询结果返回给另一个对象。这本身似乎很疯狂。 Microsoft创建了var匿名数据类型,并建议使用它,但是无法将此数据移出本地方法,因此如果必须使用检索它的同一函数中的数据,则oo范例会中断。

  • 表格不是对象。研究第三种常规形式等。关系数据库用于存储数据,而不是使用它。我不希望被限制或鼓励使用我的表作为对象。我从数据库中检索的数据通常是多个表的连接,可能包括SQL强制转换,函数,运算符等。

  • 没有性能提升,轻微损失

  • 现在我有更多代码需要担心。有dbml文件,仍然是实际编写LINQ的DAL。是的,很多是机器生成的,并不意味着它不存在,它可能出错的其他东西(即你的dbml文件等)。

现在我已经给出了背景知识,我将尝试回答你实际问题,为什么人们使用LINQ To SQL:

  • 这是微软的最新消息,我希望在我的简历中使用它。
  • Msft确信经理/高管会减少编码时间
  • 开发人员讨厌SQL。 (除了手动之外没有好的开发环境或调试 - 对sql工具有更好的智能感知会很好。)

我鼓励人们不要仅仅因为其他人都是这样做,学会把它放在你的简历上,如果被迫,就愿意使用它,但首先尝试并真正理解利弊。

答案 10 :(得分:-2)

简单的回答,有两种方法:创建精美的Rube Goldberg contraptions,或者只是以简单的方式完成工作。许多开发人员倾向于前者。

开发人员很容易感到厌倦,并且经常个人喜欢以更难的方式做事,这似乎提供了一定的知识美。你在开发应用程序还是写博士?由于我的msft导演过去常常在走廊里喊叫,“我不想要另一个研究项目!”