如何在C#中嵌入SQL查询

7
我正在使用C#编写一个新项目,其中包含许多SQL查询。有些查询相对较大且复杂。我想知道最佳的存储方式是什么。理想情况下,我会在数据库上创建存储过程,但其他许多应用程序也在使用该数据库,所以最好将适用于我的应用程序的存储过程保留在应用程序中。
选项似乎有以下几种:
  1. 字符串字面量(const string query ="Select * From MyTable"
    • 优点:简单,短小
    • 缺点:没有语法高亮,长查询时混乱
  2. 为每个查询创建一个文件,如QueryName.sql
    • 优点:语法高亮,对于大型复杂查询更整洁
    • 缺点:对于许多查询需要许多文件(每个文件一个查询),从内容文件中读取查询可能会更慢
  3. 还有其他想法吗?
作为另外一种想法,是否有一种方法可以轻松地从SQL查询生成强类型的类定义?

如果你想使用存储过程,为什么要使用ORM? - Oded
你能不能在应用程序专用模式下不创建SP? - kͩeͣmͮpͥ ͩ
你已经用 "entity-framework" 标记了你的问题 - 你在使用它吗?你不需要 "raw" SQL - 只需查询实体框架上下文即可。 - Graham Clark
@Oded 目前我不是,虽然我正在考虑是否像 EF 或 LINQ to SQL 这样的东西更有意义。过去我一直坚持使用纯 SQL,因为我发现 LINQ to SQL 很难做到性能好且没有 bug。 - ForbesLindesay
2
可能是执行存储为资源的SQL脚本的重复问题。 - Michael Freidgeim
显示剩余2条评论
3个回答

21

另一种选项是:

4:将每个查询作为 QueryName.sql 文件创建,并将其作为嵌入式资源嵌入到您的程序集中。这样,您就不会在磁盘上有物理文件,但是您的 SQL 查询已经整齐地嵌入到 Visual Studio 解决方案中的单独文件中,您可以轻松地从这些嵌入式资源中提取 SQL 文本并应用于您的 SqlCommand 对象。

查看以下资源,了解如何开始:


这符合我所尝试使用的风格,因此标记为答案。 - ForbesLindesay
1
缺点是在视觉工作室的错误列表中会显示用于原地参数(Oracle)的冒号... - klaasjan69
1
已解决:https://dev59.com/pW445IYBdhLWcg3wws4u - klaasjan69

2

为什么不直接使用Entity Framework或Linq-to-SQL?

如果你有一个名为Foos的表,你最终会得到如下代码:

using(var db = new MyEntityBase()){

    var selectedFoo = from foo in db.Foos
                      where foo.Bar > 4
                      select foo;
    //Do stuff
}

这将转换为SQL语句:

select * from Foos where Bar = 4

以上C#代码都是强类型的,Entity Framework将为您创建所有所需的数据类。


1
好的,应该先谷歌一下 MetadataTypeAttribute 如果其他人也想了解。 - ForbesLindesay
@ForbesLindesay,你不应该直接将实体提供给MVC,这是映射器和UiClasses(如果您喜欢,可以使用ViewModels)的作用。 - Bogdan Mart
1
@Rune FS 有很多事情是无法使用EF来完成的,比如复杂的聚合和递归CTE。我正在使用_context.Database.SqlQuery<MyEntityClass>("SQL查询")来实现这个功能。 - Bogdan Mart
@BogdanMart 我同意你不能用 EF 做任何事情,但由于你可以扩展 Linq-to-SQL 来适应你的需求,你在 Linq-to-SQL 中所能做的一切都可以在 SQL 中完成。你甚至可以做更多的事情。我们曾经将外部授权集成到我们的 Linq 查询中。这是否值得努力?嗯,这基本取决于具体情况,但是它肯定是可行的。 - Rune FS
@RuneFS 这很有趣,谢谢你的提示,我会考虑扩展IQueriable。但是我并没有在整个项目中使用EF,而是在Repository中使用它,并且可以将可移植到LINQ的复杂SQL从单个方法中调用,这应该由集成测试覆盖。是否可能扩展LINQ以使其理解递归CTE? 我认为可以,但我需要与EF Core紧密集成。你能给我一个参考,框架如何生成查询吗? - Bogdan Mart
显示剩余2条评论

0

我会选择像EF或Subsonic这样的ORM。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接