我有一个与SQL Server通信的Web应用程序。我没有硬编码所有查询字符串,而是选择将它们存储在全局资源文件中。那被认为是不好的做法吗?
另外,当我这样做时,Visual Studio会向我大吼大叫SQL注入的可能性,尽管这些查询被参数化(更不用说资源文件中的“拼写”警告)。
答案 0 :(得分:10)
实践属于范围(例如避免,首选,使用等)并依赖于背景。
如果你从高处获得了一个不能使用存储过程的任务,你也不能使用ORM,那么将复杂的SQL存储为资源并不是一种实践,因为你至少没有逃避System.String
中的角色,至少让你保持一定的安全。如果您的SQL本质上是动态的,那么将资源文件与文本模板机制相结合是相当干净的。
尽管如此,除非在维护成本,可读性和功能方面有明显的好处,否则应该避免使用资源文件的(通常在大多数情况下)。将存储过程绑定到代码有很多简洁的方法;有许多称职的ORM工具和小型数据访问层可能会做得更好。
答案 1 :(得分:8)
将SQL查询与应用程序代码分开是一件好事。存储过程是执行此操作的常规方法,但如果这不可行并且您必须直接使用SQL,我认为您的方法很好。最新版本的SQL Server参数化查询在第一次运行时进行预编译,并提供与SP类似的性能。
我建议你研究其他数据访问方法,例如linq-to-sql,它可以自动生成SQL查询,并为代码提供更清晰的界面。
答案 2 :(得分:5)
资源文件definitley不是这个地方。资源文件的要点是可以本地化的事物的集中存储库(即被其他语言/文化定义的其他资源文件覆盖)。
例如,您在"Hello"
中添加了字符X.resources.dll
,但您也可以为西班牙语创建es-ES\X.resources.dll
,其中字符串会显示"Hola"
而不是 - 当你的应用程序查询字符串时,它将获得与用户操作系统配置的语言/文化相匹配的任何版本。
如果您希望在不重新编译代码的情况下轻松更改SQL,请将其放在App.config
中并使用ConfigurationManager
类将其读出。如果您不希望在没有代码重新编译的情况下更改它,只需将该事物硬编码为static
/ const
string
。也就是说,理想当然是制作真正的存储过程。
答案 3 :(得分:4)
我认为很多人认为硬编码SQL是一种不好的做法,无论它是如何存储的......: - )
我将假设有一些令人信服的理由不使用Linq to SQL,Entity Framework或其他ORM工具?
如果你必须在你的应用程序中使用硬编码SQL,那么会认为它在你的代码中是更好的内联,因为它使你的代码更具可读性,因此更易于维护......
答案 4 :(得分:3)
这样做我没有看到任何特别“坏”的东西。它实际上与在代码中对sql代码进行硬编码没什么不同,只是与在运行时生成SQL ad-hoc的情况略有不同。
您说您正在使用参数化查询,因此您不必担心脚本注入。
如果要将sql存储在资源文件中以遵守DRY原则,那么您可能希望使用某种DAL来实现此目的。像实体框架(EF)或Linq-to-SQL
答案 5 :(得分:3)
我使用这种模式构建了一个应用程序 - 在PHP中,而不是.Net,但原则是相同的。
<强>优点:
<强>缺点:
根据我的经验,这些好处不会与缺点相悖。
BTW - 许多缺点也适用于存储过程。使用存储过程有一个很好的例子 - 但是同样好的情况是不使用它们。答案 6 :(得分:1)
这不一定是不好的做法,但如果需要打开另一个文件并找到正确的密钥,它会让您更难读取程序。
Visual Studio抱怨,因为它无法看到该值是常量,并且它始终来自可靠来源。
在源文件中使用SQL不会比在源文件中包含其余程序代码更“硬编码”。你为什么要这样做呢?要重新使用查询?也许你应该考虑商店程序......
答案 7 :(得分:0)
我想到的是,这只会给代码增加不必要的复杂性。
是的,您可以将查询保留在资源文件中。或者,为了确保在部署项目后没有人与他们混淆,您可以加密它们并将它们存储在文件中。或者更好的是,你可以对它们进行加密,然后将它们存储在一个数据库中,以便没有人能够访问这台机器。
但最终,我不得不问,重点是什么?只需对它们进行硬编码即可完成。
KISS。
答案 8 :(得分:0)
您可以编写存储过程并在代码中调用它们,而不是读取存储在外部的查询。