C# 在C中使用ADO.NET格式化内联sql的最佳实践是什么#

C# 在C中使用ADO.NET格式化内联sql的最佳实践是什么#,c#,sql,ado.net,C#,Sql,Ado.net,我知道这里有很多关于内联sql和存储过程的问题。。。 我不想再开始这样的一次!这是关于内联(或动态)sql的 我还知道,这一点在LINQtoSQL及其后续实体框架中或多或少已经变得毫无意义 但是假设您选择(或上级要求)使用普通的旧ADO.NET和内联(或动态)sql。那么,在这方面和格式化sql方面的最佳实践是什么 我现在做的是: 我喜欢先在存储过程中创建SQL语句。这使我能够在SQLServerManagementStudio中使用语法着色,并且能够轻松地测试查询,而无需通过我正在开发的应用程

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

我还知道,这一点在LINQtoSQL及其后续实体框架中或多或少已经变得毫无意义

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

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

因此,只要我正在实现/调试,我的代码就会如下所示:

    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
            }
        }
    }
    private string GetQuery()
    {
        return @"
    SET NOCOUNT ON;
    SELECT col1, col2 from tableX where id = @id

    -- more sql here
        ";
    }
调试和测试阶段完成后,我将对上面的代码进行如下更改:

    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
            }
        }
    }
    private string GetQuery()
    {
        return @"
    SET NOCOUNT ON;
    SELECT col1, col2 from tableX where id = @id

    -- more sql here
        ";
    }
我还添加了一个额外的私有方法,例如,
GetQuery()
,在该方法中,我复制/粘贴存储过程的整个块,如下所示:

    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
            }
        }
    }
    private string GetQuery()
    {
        return @"
    SET NOCOUNT ON;
    SELECT col1, col2 from tableX where id = @id

    -- more sql here
        ";
    }
这样做的好处是,如果以后必须调试/更新sql代码,我可以轻松地还原代码以再次调用存储过程,一旦完成,我就可以轻松地使用“复制/粘贴”将sql代码放回原处,而不必在每一行加引号之类的内容

在查询中包含换行符是一种好做法吗?
是否有其他我没有想到的事情或技巧可以使这种方法更好?
你们是怎么做这种事的?
或者我是唯一一个仍然使用(必须使用)内联sql的人吗?

内联(带或不带文本
@…“
语法)对于简短的查询来说很好。。。但在更长的时间内,考虑将TSQL作为项目中的文件;可以作为嵌入式资源/resx,也可以作为平面文件。当然,到那个阶段,您可能无论如何都应该将它变成一个存储过程-p

但是将它作为一个单独的文件会强制进行同样的分离,这将使它很容易在以后变成一个存储过程(可能只是添加
createproc
等)


内联的一个问题是,它使人们很容易将用户输入连接起来。。。这显然很糟糕(您在示例中正确使用了参数)。

我过去使用过.NET资源文件。这些工具对于保存特定代码库中使用的所有查询的库非常方便,尤其是当同一查询可能在多个位置使用时(是的,我意识到这也表明一些糟糕的设计,但有时您需要在给定的框中工作)。

除了非繁琐的单行SQL语句,我总是利用多线,使它成为一个常数

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

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

LINQ to SQL并没有“正式死亡”;它仍然是一个正在开发的支持产品;简单地说,EF正在获得新功能的关注。抱歉,我只是引用了我在其他问题中发现的东西。。。删除它;-)的确,参数是将所有内容首先放入存储过程的另一个原因。。。我从不连接sql!我有时会连接sql(以遵守DRY原则)。。。但我从不将其与用户输入连接;-)如果你把它放在平面文件中,那么你如何把它放到命令中呢;当然,如果您使用resx,您会自动获得一个helper属性。resx将是我的首选-因此不,您不会部署任何东西。只需创建一个资源文件和几个tsql文件,并将tsql拖到资源设计器表面上。。。工作完成了。