使用dapper时在哪里放sql?

时间:2011-05-13 06:35:40

标签: c# asp.net-mvc-3 n-tier-architecture dapper

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

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

使用dapper时如何存储sql?

3 个答案:

答案 0 :(得分:22)

我会说将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方言),则可能用于隐藏查询隐藏在中央包装器后面的唯一其他原因。这比人们想象的要少。

答案 1 :(得分:6)

使用资源文件对我们非常有用。我们在文件夹call / Sql中创建.sql文件,并将它们拖到我们的SqlResource对象的'Files'部分。对于较小的sql片段(例如我们可能正在查询的函数),资源文件的“字符串”部分非常简洁且容易。

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

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

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

因此,总而言之,对于我们来说资源文件保持真正干净,但对于Marc Gravell而言,它们不是生产代码中的可重用性......每个sql语句只应由应用程序中的一个点使用。

答案 2 :(得分:3)

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

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