【问题标题】:How can I manage my SQL query script in asp.net mvc project?如何在 asp.net mvc 项目中管理我的 SQL 查询脚本?
【发布时间】:2017-05-23 06:00:49
【问题描述】:

我正在使用 Dapper 来处理数据。

这是一个代码示例:

using(var connection = new SqlConnection(ConfigurationManager.AppSettings["MyConnectString"])
{
     var sql = string.Format(
         @"SELECT [Column1]
             FROM [MyTable]
            WHERE [Column3] > {0}
              AND [Column4] < {1}"
         , myValue1
         , myValue2
     );
     var result = connection.Query<long>(sql).ToList();
}

我的项目写了很多类似上面的sql脚本。

我想将脚本写入文件(可能是 QueryAccount.config、QueryOrder.config、(xml 格式)或其他文件)

然后我可以从文件中加载脚本。

我想要的是在文件中编写我的脚本,然后我编写相同的类 在文件中。 (例如,我在 Product.config 中编写所有查询产品脚本,在 Order.config 中编写所有查询订单脚本) 然后我像这样使用:

var cmd = MyCommandManager.GetScript("QueryProduct");
cmd.SetParam("@ProductId", 123);
cmd.SetParam("@InvoicingDate", DateTime.Now(-7))
...

文件中的脚本如:

SELECT [ProductName]
FROM [Product]
WHERE [ProductId] = @ProductId
  AND [InvoicingDate] = @InvoicingDate

【问题讨论】:

  • 不要这样做 - 你在要求 sql 注入攻击!
  • 你为什么想要那个?
  • @DanielA.White 你能给我一些建议吗?但我必须使用 dapper...非常感谢。
  • 您应该为每个脚本创建存储过程,然后使用参数调用这些存储过程。它将避免sql注入。

标签: c# asp.net-mvc config dapper sql-scripts


【解决方案1】:

如果您对数据库具有完全访问权限,则可以尝试实现Stored Procedure 来存储 SQL 文本。您需要做的就是在 Dapper 查询中引用 Stored Proc 名称并将命令类型设置为 StoredProcedure,然后您就可以开始了,如下所示:

using(var cn = new SqlConnection("MyConnectionString"))
{
    cn.Open();
    return cn.Query<MyModel>("MyProcName", new { Parameter1 = myValue1, Parameter2 = myValue2 }, commandType: CommandType.StoredProcedure);
}

使用 SQL 参数而不是将值注入到查询中是一件非常聪明的事情,因为它可以防止 SQL 注入攻击。像这样重新格式化您的查询会有所帮助:

@"SELECT [Column1]
  FROM [MyTable]
  WHERE [Column3] > @Parameter1
  AND [Column4] < @Parameter2"

请注意,我的参数名称与上面的 dapper 调用匹配。但是,当我不使用存储过程时,我通常会在类的顶部创建一个 private const string,以引用我的“存储”查询。

public class QueryClass 
{
    private const string query = "SELECT * FROM Table1";

    public IEnumerable<MyModel> CallQuery()
    {
        // Dapper Query Details
    }
}

我订阅了Command/Query Pattern like this one,所以我从来没有遇到过查询存储问题,因为每个类通常都有一个查询。

编辑

如果你喜欢命令/查询模式,我建议你查看MediatR,因为它是这种模式的一个很好的实现。

第二次编辑

我通过将 SQL 查询添加到某种配置文件来了解您正在尝试做什么,但是如果可以的话,我想建议您不要这样做。在我的上一份工作中,所有 SQL 查询都存储在编译到应用程序中的 XML 文件中。这似乎是一种管理查询的有效方法,但是一旦应用程序增长到甚至只有几个 SQL XML 文件,我们就很难管理可以在哪里找到哪些查询,最终我们的查询在多个 XML 文件中重复。我们还遇到了许多拼写错误和其他 XML 结构错误的问题,这些错误直到运行时才被发现,但我想您可以在任何字符串中出现拼写错误,这样就不一定会消失。它最终变得一团糟,导致的问题多于解决的问题。

我相信让 SQL 查询文本尽可能接近需要它的代码是一个更好的选择,如果您在命名空间和组织查询对象方面很聪明,您可以让开发人员通过以下方式轻松找到查询智能感知。

【讨论】:

    【解决方案2】:

    忽略反对者。 SQL 应始终位于其自己的文件中。这些文件的扩展名应为 .sql,而不是 .config。因此,它们将在 VS SQL 编辑器中进行编辑,非常舒适。我认为每个查询都需要一个文件。通过在同一个文件中分组不同的查询没有任何收获。我建议将这些文件放在使用它们的 .cs 文件旁边,将您一起打开的文件和您可能希望有一天删除的文件组合在一起。

    创建后,右键单击解决方案资源管理器中的 .sql,属性 --> 构建操作 --> 嵌入式资源。然后,在您的 MyCommandManager.GetScript() 方法中,使用 GetManifestResourceStream() 访问查询文本。与存储过程相比,这具有巨大的优势,即您的查询是使用调用代码编译的,因此您不必担心存储过程和应用程序的版本同步。

    如果这一切看起来需要做很多工作,那就是。这就是为什么没有人这样做,但他们应该 :-) 抓住 QueryFirst,它会为你完成,除此之外还有很多其他事情。免责声明:我编写了 QueryFirst。

    【讨论】:

      猜你喜欢
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 2013-09-18
      • 2018-04-10
      • 2013-07-11
      相关资源
      最近更新 更多