【问题标题】:What are the best practices on formatting inline sql using ADO.NET in C#在 C# 中使用 ADO.NET 格式化内联 sql 的最佳实践是什么
【发布时间】:2009-06-05 10:33:39
【问题描述】:

我知道这里有很多关于内联 sql 与存储过程的问题...... 我不想再开始这样的一个!这个是关于内联(或动态)sql的。

我也知道,对于 Linq to SQL 及其后续实体框架,这一点或多或少变得没有意义。

但是... 假设您已选择(或您的上级要求)使用普通的旧 ADO.NET 和内联(或动态)sql。那么这方面和格式化 sql 的最佳实践是什么?

我现在要做的是: 我喜欢先在存储过程中创建我的 SQL 语句。这使我能够在 SQL Server Management Studio 中进行语法着色,并且能够轻松测试查询,而无需通过我正在开发的应用程序在代码中执行它。

所以只要我在实现/调试,我的代码看起来像这样:

    using (SqlConnection conn = new SqlConnection("myDbConnectionString"))
    {
        conn.Open();
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "myStoredProcName";
            // add parameters here
            using (SqlDataReader rd = cmd.ExecuteReader())
            {
                // read data and fill object graph
            }
        }
    }

调试和测试阶段完成后,我将上面的代码更改如下:

    using (SqlConnection conn = new SqlConnection("myDbConnectionString"))
    {
        conn.Open();
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = GetQuery();
            // add parameters here
            using (SqlDataReader rd = cmd.ExecuteReader())
            {
                // read data and fill object graph
            }
        }
    }

我添加了一个额外的私有方法,例如GetQuery() 我在其中复制/粘贴整个存储过程块,如下所示:

    private string GetQuery()
    {
        return @"
    SET NOCOUNT ON;
    SELECT col1, col2 from tableX where id = @id

    -- more sql here
        ";
    }

这样工作的好处是,如果以后必须调试/更新 sql 代码,我可以轻松地恢复代码以再次调用存储过程,一旦完成,我可以通过复制/粘贴轻松地将 sql 代码放回原处, 不必在每一行都加上引号和类似的东西

在查询中包含换行符是一种好习惯吗?
还有其他我没有想到的东西或技巧可以使这种方法更好吗?
你们是怎么做这样的事情的?
还是只有我一个还在使用(必须使用)内联 sql?

【问题讨论】:

  • LINQ-to-SQL 不是“正式死亡”;它仍然是一个持续开发的受支持产品;简而言之,EF 正在关注新功能。
  • 抱歉只是引用了我在其他问题中找到的内容...删除它;-)

标签: c# sql ado.net


【解决方案1】:

内联(有或没有文字 @"..." 语法)适用于短查询……但对于更长的查询,请考虑将 tsql 作为项目中的文件;作为嵌入式资源/ resx,或作为平面文件。当然,到那个阶段,你可能应该把它变成一个存储过程;-p

但是将它作为一个单独的文件会强制进行相同的分离,这将使以后变成存储过程变得轻而易举(可能只是添加CREATE PROC 等)。

内联的一个问题 - 它让某人很想连接用户输入...这显然很糟糕(您在示例中正确使用了参数)。

【讨论】:

  • 是的,参数是首先将所有内容放在存储过程中的另一个原因...我从不连接 sql!
  • 好吧,我有时会连接 sql(以遵守 DRY 原则)...但我从不将它与用户输入连接 ;-)
  • 如果你把它放在平面文件中,那么你如何将它放入命令中呢?
  • 通过读取文件;当然,如果你使用 resx,你会自动获得一个辅助属性。
  • resx 是我的偏好——所以不,你不会部署任何东西。只需创建一个资源文件和几个 tsql 文件,然后将 tsql 拖到资源设计器表面……就完成了。
【解决方案2】:

我过去使用过 .NET 资源文件。这些对于保留特定代码库中使用的所有查询的库非常方便,特别是当可能在多个地方使用相同的查询时(是的,我意识到这也表明设计不佳,但有时您需要在给定的框中工作给你)。

【讨论】:

    【解决方案3】:

    除了非平凡的单行 SQL 语句之外,我总是利用多行并将其设为 const

        const string SelectMyTable = @"
    SELECT column_one
         , column_two
         , column_three
      FROM my_table
    ";
    

    这一切都允许我剪切并粘贴到 SQL 管理器进行测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-29
      • 2013-04-09
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多