使用 LINQ 执行查询和内联操作的普遍共识是什么?这与将 SQL 语句嵌入代码有什么不同(这被认为是不可以)?
9 回答
忽略 LINQ 的所有非 SQL 相关用途,只考虑 LINQ-to-SQL。
LINQ 查询是保留查询定义的对象,等效的 SQL 仅在查询实际迭代时才实例化。这允许组件被正确分离并允许管道样式处理,其中查询由较低层(例如,由存储库)返回并由堆栈上的较高组件转换。查询可以容纳来自处理管道中每个组件的新过滤器、连接和其他“工件”,直到它到达最终迭代的最终形式。这种操作在实践中使用纯文本 SQL 是不可能的。
LINQ 的另一个优点是它的语法对于非数据库开发人员来说更容易理解。SQL 语法专业知识是一项令人惊讶的难以找到的资产。很少有开发人员愿意花时间学习 SQL 之外的更细微的点SELECT * FROM ... WHERE ...
. linq 语法更接近 .Net 日常环境,并利用该层的现有技能集(例如 lambda 表达式),而不是强迫开发人员为目标后端(T-SQL、PL-SQL)学习正确的 SQL ETC)。鉴于 linq 表达式在关系代数中非常直接地表达了所需的结果,提供者可以更轻松地生成适当的 SQL(甚至直接生成执行计划!)。将此与“通用”数据库驱动程序必须面对 SQL 文本的不可能任务进行比较。还记得 ODBC 转义语法吗?
你是对的:“在你的代码中嵌入 SQL 语句还不错。” 这很糟糕。
这样做会使您的应用程序高度耦合、脆弱且难以维护。至少,如果您在 procs 中拥有所有内容,那么当您更改某些内容时,您可以搜索依赖项。
存储过程,对于那些处理业务逻辑的过程,我觉得真的需要离开。
原因是业务逻辑属于业务层——而不是数据层。
当然,如果生成的 Linq to SQL 变得混乱且缓慢,那么您必须使用 proc。
Linq To SQL 的一大优势是您可以将过滤器链接在一起——您的 where 子句只是根据需要通过您的逻辑动态添加。您不需要仅仅因为您想调用基于多个参数的一组数据而创建新的过程。
在代码中嵌入 SQL 语句也不错。这一切都取决于您正在编写它们的应用程序的哪一层。
与读取和写入数据存储相关的任何内容都应该在数据访问层上。
“Linq To Sql” 与“inline SQL”(最常见的最坏情况)相比的两个优点。
参数被视为参数,而不仅仅是连接文本——这克服了 SQL 注入问题。
单独的模型层允许编译时检查生成的 sql 是否与模式匹配。(例如,在最坏的内联 sql 情况下,您无法在编译时知道您是否引用了已删除的列)
一方面,LINQ 语句是参数化的——内联查询不一定是这样。另一方面,LINQ 基本上创建了一个 ORM 层——允许将数据库对象本质上视为代码中的对象——提供编译时检查。另一方面,内联查询是一个不会在编译时中断的文本块......
看看其他答案,也许我误解了这个问题......但我说的是 C# 中集合上的普通 LINQ,而不是 LINQ-to-SQL:
当您在代码中嵌入SQL语句(而不是使它们成为变量或以其他方式参数化您的 SQL)时,如果您想在将来支持不同的数据库,您将变得更加困难。尽管 SQL 已经过时和标准化,但供应商之间仍然存在许多不兼容之处。
使用 LINQ,可移植性不再是问题——您的代码是用 C# 编写的,而 LINQ是C#。
据我所知,无论您使用 LINQ-to-SQL 还是任何其他 ORM 或您自己的包装 SQL 调用的代码,它基本上都为您提供了一个抽象,您不必担心 SQL。
此外,如果我是正确的 - LINQ to SQL 仅支持 SQL Server。
我认为,它允许您使用 LINQ 语法以类似 SQL 的方式构建您的标准。
就个人而言,我不知道为什么有人会使用 LINQ to SQL。
专家可以帮助我了解它的需要吗?
在某行代码中,某个人有时会决定是否适合键入 SQL。但是,您将使用 LINQ,而不是这样做。
因此,当 SQL 不应该内联时,是否应该内联 LINQ 并不重要。问题是您希望数据存储访问表示在哪里。如果您在某行代码中编写 LINQ,并且您对这个范围可以访问存储的数据感到不自在,那么这是错误的地方。
LINQ 只是数据操作的抽象。这是过滤集的快捷方式。就像数据库理解 SQL 一样,.NET 环境也有一种与数据对话的语言。
LINQ 和在循环内、在来自文件或网络套接字的数据上执行 if 语句有什么区别?没有,这只是语法。如果您根据函数过滤每一行,那么与使用 LINQ 有什么SELECT * FROM table
区别?where c.SomeProperty < x
只是语法。
当然,LINQ 知道并做的不仅仅是从数据库中返回行。它允许您从集合中实例化对象,但也可以= new ClassName(column1, colum2)
从 SQL 语句结果中实例化对象。
简而言之,如果在你的代码中写内联 SQL 的地方是不行的,那么它应该写 LINQ。
但这因项目而异。数据库大多理解 SQL,因此至少在您的代码、库或环境中的某个地方存在内联 SQL。
广泛使用嵌入式 SQL,真正的危险在于它是一种代码生成技术。您编写 C 代码(或任何语言),然后切换到 SQL,然后再次返回 C。稍后在编译之前,前处理器将代码重写为全 C。结果可能会产生非常混乱的错误消息。您被迫学习 API 与数据库交互,嵌入式 SQL 应该让您从中解放出来。最后,您冒着将业务规则嵌入到查询中的风险,混淆了业务层和数据层。Linq 避免了其中一些问题。首先,Linq 是语言的一部分。这些结构或多或少像程序员所期望的那样工作。涉及到一些 SQL 类型的语法,但大多数语法都集中在宿主语言(即 C#)上。编译检查是在您编写的实际代码上完成的。因此不需要在预处理之前将错误翻译成语法。正如您所期望的那样,查询的结果是对象和集合。然而,在数据层中混合业务逻辑仍然存在危险。此外,Linq 有它自己的错误消息问题,其中相关字段通常不包括在内。它仍然是对象世界和关系世界之间的良好折衷。