使用dapper时将sql放在哪里

本文关键字:在哪里 sql 时将 dapper 使用 | 更新日期: 2023-09-27 17:56:13

我在工作中将dapper用于mvc3项目,我喜欢它。但是,在使用dapper时,您应该如何分层应用程序?目前我只是将所有sql直接塞进控制器(slap),但我正在考虑用静态字符串制作一个类。所以我可以做

var reports = Dapper.Query<Report>(conn, MySql.ReportsRunningQuery)

使用 dapper 时如何存储 sql?

使用dapper时将sql放在哪里

我会说把sql放在你可以放置等效的LINQ查询的地方,或者把sql放在DataContext.ExecuteQuery的地方。至于那是什么...好吧,这取决于你,取决于你想要多少分离。

但是,就我个人而言,我认为将SQL隐藏在远离Query<T>调用的单独类中没有任何好处-您希望在上下文中查看它们,以便可以轻松验证数据(实际上是参数)。您可能还在原位构造查询(仍参数化)。但是对于常规静态查询,我会将 TSQL 保留为代码附近的文字,除非我有充分的理由需要对其进行抽象,即

var reports = conn.Query<Report>(@"
select x.blah, y.blah
from x (snip)
where x.ParentId = @parentId and y.Region = @region", new {parentId, region});

(另请注意上述替代扩展方法的用法)

IMO,上面的关键是,您极不可能任何其他地方重用该查询 - 逻辑将被放入一个方法中,并且该方法从多个位置调用。因此,您可能用来将查询隐藏在中央包装器后面的唯一其他原因是,如果您需要支持不同的数据库提供程序(使用不同的 SQL 方言)。这比人们想象的要少见。

使用资源文件对我们来说非常有用。 我们在名为/Sql 的文件夹中创建.sql文件,并将它们拖到 SqlResource 对象的"文件"部分。 资源文件的"字符串"部分非常干净,对于较小的sql片段(例如,我们可能正在查询的函数)来说很容易。

所以,我们的 sql 看起来像:

var reports = conn.Query<Report>(SqlResource.Blahs_get, new {parentId, region});

这样可以保持存储库的真正干净。 将所有 sql 放在资源文件中还有其他好处,因为您可以迭代条目并可能使用 PARSEONLY 查询数据库,以确保如果数据库对象更改,您的查询会中断(请注意,这主要是但不是 100% 可靠的)。

所以,总而言之,对我们来说,资源文件保持了真正的干净,但对于 Marc Gravell 的观点,它们不是为了在生产代码中重用......每个 SQL 语句只能由应用程序中的一个点使用。

虽然这个问题现在已经相当老了,但我想进一步建议SQL的外部存储。Visual Studio(至少2015+)具有语法突出显示,以及用于*.sql文件的小型调试器和连接管理器。这些文件可以进一步标记为嵌入的资源,并完全包含在程序集中,但与代码分开。你会越来越讨厌看到无色的SQL嵌入在未经语法验证的字符串中。

我已经在我最近的所有项目中采用了这种模式,并结合像Dapper这样的ORM,C#和SQL之间的接口变得非常少。我在GitHub上有一个扩展Dapper的开源项目,可以提供示例,以及NuGet包。它还包括一个受 moustache 启发的字符串替换引擎,这对于模板化脚本以使其可重用或插入动态过滤条件非常有用。