简体   繁体   English

将多个SqlParameter传递给方法

[英]Passing multiple SqlParameter to method

In my main form, I have implemented this code.. 在我的主要表单中,我已实现此代码..

void SampleMethod(string name, string lastName, string database)
{
        SqlParameter sqlParam = new SqlParameter();
        sqlParam.ParameterName = "@name";
        sqlParam.Value = name;
        sqlParam.SqlDbType = SqlDbType.NVarChar;

        SqlParameter sqlParam1 = new SqlParameter();
        sqlParam1.ParameterName = "@lastName";
        sqlParam1.Value = lastName;
        sqlParam1.SqlDbType = SqlDbType.NVarChar;

        SqlParameter sqlParam2 = new SqlParameter();
        sqlParam2.ParameterName = "@database";
        sqlParam2.Value = database;
        sqlParam2.SqlDbType = SqlDbType.NVarChar;

        SampleClass sampleClass = new SampleClass(new DBConn(@serverName, tableName, userName, password));
        sampleClass.executeStoredProc(dataGridView1, "sp_sampleStoredProc", sqlParam, sqlParam1, sqlParam2);
}

And in my SampleClass , I have this kind of method. 在我的SampleClass ,我有这种方法。

public DataGridView executeStoredProc(DataGridView dtgrdView, string storedProcName, params SqlParameter[] parameters)
{
        try
        {
            DataTable dt = new DataTable();
            sqlDA = new SqlDataAdapter(storedProcName, sqlconn);
            sqlDA.SelectCommand.CommandType = CommandType.StoredProcedure;
            sqlDA.SelectCommand.CommandTimeout = 60;

            // Loop through passed parameters
            if (parameters != null && parameters.Length > 0)
            {
                foreach (var p in parameters)
                    sqlDA.SelectCommand.Parameters.Add(p);
            }

            sqlDA.Fill(dt);
            dtgrdView.DataSource = dt;
            sqlconn.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            sqlconn.Close();
        }

        return dtgrdView;
}

What I am trying to do is avoid multiple 我想做的是避免多重

SqlParameter sqlParam = new SqlParameter() 

in my code, I have tried so many solutions for this problem but I didn't get the right answer. 在我的代码中,我已经为这个问题尝试了很多解决方案,但我没有得到正确的答案。 I have also tried to research about this but I still couldn't get the right answer. 我也尝试过对此进行研究,但我仍然无法得到正确答案。

Please don't mind my naming convention and other codes as I intentionally change many of them :) Thanks. 请不要介意我的命名约定和其他代码,因为我故意改变其中许多:)谢谢。

As an alternative to your solution, try to use already existing one instead, using Dapper ( https://github.com/StackExchange/dapper-dot-net ). 作为您的解决方案的替代方案,请尝试使用已有的解决方案,使用Dapper( https://github.com/StackExchange/dapper-dot-net )。

You still need to use multiple parameters if your stored procedure or query needs it, but this is nicely abstracted for you and this will definatelly reduce the amount of code. 如果您的存储过程或查询需要,您仍然需要使用多个参数,但这很好地为您抽象,这将最终减少代码量。

void SampleMethod(string name, string lastName, string database)
{
    using(var connection = new SqlConnection(MY_CONNECTION_STRING))
    {
        var resultListOfRows = connection.Query<ReturnObject>(MY_STORED_PROCEDURE, new { 
            name = name,
            lastName = lastName,
            database = database}, commandType: System.Data.CommandType.StoredProcedure);
    }
}

Separate your Database logic at one place(put sqladapter, sqlcommand etc at one place), Then encapsulate parameters within your command like mentioned below and you don't need to declare sqlparameter separately, add it inside parameters list. 在一个地方分离你的数据库逻辑(把sqladapter,sqlcommand等放在一个地方),然后在你的命令中封装参数,如下所述,你不需要单独声明sqlparameter,将它添加到参数列表中。

 cmdToExecute.Parameters.Add(new SqlParameter("@parameter", value));

Take a look at the complete example below 看看下面的完整示例

    public DataTable ProdTypeSelectAll(string cultureCode)
    {
        SqlCommand cmdToExecute = new SqlCommand();
        cmdToExecute.CommandText = "dbo.[pk_ProdType_SelectAll]";
        cmdToExecute.CommandType = CommandType.StoredProcedure;
        DataTable toReturn = new DataTable("ProdType");
        SqlDataAdapter adapter = new SqlDataAdapter(cmdToExecute);
        cmdToExecute.Connection = _mainConnection;
        cmdToExecute.Parameters.Add(new SqlParameter("@CultureName", cultureCode));
        _mainConnection.Open();
        adapter.Fill(toReturn);
        return toReturn;
}

First of all, the easiest option would be to use a microORM like Dapper, and retrieve a strongly-typed collection. 首先,最简单的选择是使用像Dapper这样的microORM,并检索强类型集合。 Gridviews can bind to anything, including strongly typed collections. Gridview可以绑定到任何东西,包括强类型集合。 All this code could become: 所有这些代码都可能成为:

using(var con=new SqlConnection(myConnectionString))
{
    con.Open();
    var result= connection.Query<ResultClass>("sp_MySproc", 
                         new { Name= name, LastName= lastName,Database=database},
                         commandType: CommandType.StoredProcedure);
    return result;
}

Even when using raw ADO.NET, you can create a SqlParameter in one line by using the appropriate constructor . 即使使用原始ADO.NET,也可以使用适当的构造函数在一行中创建SqlParameter。 For example, you can create a new nvarchar(n) parameter with: 例如,您可以使用以下命令创建新的nvarchar(n)参数:

var myParam=new SqlParameter("@name",SqlDbType.NVarchar,20);

or 要么

var myParam=new SqlParameter("@name",SqlDbType.NVarchar,20){Value = name};

A better idea though is to create the SqlCommand object just once and reuse it. 但更好的想法是只创建一次SqlCommand对象并重用它。 Once you have an initialized SqlCommand object, you can simply set a new connection to it and change the parameter values, eg: 一旦有了初始化的SqlCommand对象,就可以简单地设置一个新连接并更改参数值,例如:

public void Init()
{
    _loadCustomers = new SqlCommand(...);
    _loadCustomers.Parameters.Add("@name",SqlDbType.NVarChar,20);
    ...
}

//In another method :
using(var con=new SqlConnection(myConnectionString)
{       
    _loadCustomers.Connection=con;
    _loadCustomers.Parameters["@name"].Value = myNameParam;
    con.Open();
    using(var reader=_load.ExecuteReader())
    {
    //...
    }
}

You can do the same thing with a SqlDataAdapter, in fact that's how Windows Forms and Data Adapters are meant to be used since .NET 1.0 . 您可以使用SqlDataAdapter执行相同的操作,事实上,自.NET 1.0以来,Windows Forms和数据适配器的使用方式就是这样。

Instead of creating a new one each time you want to fill your grid, create a single one and reuse it by setting the connection and parameters before execution. 每次要填充网格时,不要创建新的网格,而是创建一个网格并通过在执行前设置连接和参数来重复使用它。 You can use the SqlDataAdapter(SqlCommand) constructor to make things a bit cleaner: 您可以使用SqlDataAdapter(SqlCommand)构造函数使事情更清晰:

public void Init()
{
    _loadCustomers = new SqlCommand(...);
    _loadCustomers.Parameters.Add("@name",SqlDbType.NVarChar,20);
    ....
    _myGridAdapter = new SqlDataAdapter(_loadCustomers);
    ...
}

And call it like this: 并称之为:

using(var con=new SqlConnection(myConnectionString))
{
    _myGridAdapter.SelectCommand.Connection=con;
    _myGridAdapter.SelectCommand.Parameters["@name"].Value =....;
    con.Open();

    var dt = new DataTable();
    _myGridAdapter.Fill(dt);
    dtgrdView.DataSource = dt;
    return dtgrdView;
}

You may be able to use the SqlParameter Constructor (String, Object) . 您可以使用SqlParameter构造函数(String,Object) Replace: 更换:

sampleClass.executeStoredProc(dataGridView1,
        "sp_sampleStoredProc",
        sqlParam,
        sqlParam1,
        sqlParam2);

With: 附:

sampleClass.executeStoredProc(dataGridView1,
        "sp_sampleStoredProc",
        new SqlParameter("@name", (object)name),
        new SqlParameter("@lastName", (object)lastName),
        new SqlParameter("@database", (object)database));

However, doing this is unlikely to make your code any faster, but will reduce readability. 但是,这样做不太可能使您的代码更快,但会降低可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM