使用SqlCommand的最佳实践

时间:2011-07-28 17:43:03

标签: c# sql-server visual-studio-2010 sql-server-2008 .net-4.0

我想确保在使用SqlCommand时我使用的是最佳做法,特别是在安全方面。

我不确定的注意事项:

  1. 通过追加手动构建字符串是否可以?如果没有,我该怎么做?
  2. 我应该使用哪些课程来代替?

7 个答案:

答案 0 :(得分:5)

如果您的第一个问题是通过直接包含来讨论构建SQL,那几乎可以肯定。它可以让您了解SQL注入攻击以及转换问题(例如,必须获得正确的日期/时间格式)。

相反,您应该使用参数化查询,并在参数中设置值。有关示例,请参阅SqlCommand.Parameters的文档。

出于兴趣,您是否有特殊原因直接使用SQL而不是使用众多ORM中的一个? (LLBL,实体框架,NHibernate,LINQ to SQL,SubSonic,Massive,SimpleData,Dapper ...)

答案 1 :(得分:2)

我想说参数的使用是安全性最重要的方面之一。这将阻止SQL注入您的数据库。以下SQLCommand是我如何构建一个的例子(在VB.NET中,道歉 - 没有C#知识 - 但是;)

Dim cmd as New SqlCommand("sp_StoredProcedure", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("@ID",sqldbtype.int).value = myID
cmd.executenonquery

内联SqlCommand的一个例子:

Dim cmd as New SqlCommand("SELECT Name, Message FROM [Table] WHERE ID=@ID", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("@ID",sqldbtype.int).value = myID
cmd.executenonquery

答案 2 :(得分:2)

我的建议:懒惰。编写大量代码是一种很好的方法来制造脑死亡错误(错误的数据类型,空检查,丢失Dispose()等),并且它比许多辅助工具具有性能优势。 / p>

就个人而言,我是小巧玲珑的忠实粉丝(但我有点偏颇),这让事情变得简单:

int customerId = ...
var orders = connection.Query<Order>(
    @"select * from Customers where CustomerId = @customerId",
    new { customerId });

为你做参数化和实现,没有痛苦,而且愚蠢的快。

对于其他场景,特别是当您想使用OO技术更新系统时,诸如EF或L2S之类的ORM将为您节省工作时间(并通过LINQ为您提供更好的类型检查)。

答案 3 :(得分:0)

因为当我做POC或个人小项目时,我通常会手动构建我的字符串,但是当我在项目中工作时,我们有一个用于数据库使用和连接的模板,我必须使用它,显然无法在这里显示。

但我认为在小型项目或POC中手动构建基本操作是可以的。

  • 编辑:就像Jon说的那样,在构建自己的命令时,你应该总是使用像SqlCommand.Parameters这样的东西。对不起,如果我不清楚。

答案 4 :(得分:0)

如果您担心安全性,我建议您在SQL Server数据库中创建查询作为存储过程(以防止担心SQL注入),然后从前端代码,只需生成SQL存储过程,添加参数,并以这种方式。

This文章可以帮助您进行设置。

答案 5 :(得分:0)

您应该始终使用通过存储过程与数据库通信来对数据库连接应用最小权限的做法。

存储过程

using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
  DataSet userDataset = new DataSet();
  SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
  myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
  myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
  myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
  myCommand.Fill(userDataset);
}
  • 数据库连接字符串的凭据: A.企业/内联网的集成安全性 B.将其加密到注册表或托管提供商的文件中。

  • 一直在寻找黑客试图将交叉脚本上传到您的表单中。

  • 始终检查SQL注入的输入。

答案 6 :(得分:0)

我认为这是最好的解决方案

    SqlConnection cn = new SqlConnection(strCn);
        try
        {
            using (SqlCommand cmd = new SqlCommand("select * from xxxx", cn))
            {
                cn.Open();

                //do something

                cn.Close();
            }
        }
        catch (Exception exception)
        {
            cn.Close();
            throw exception;
        }