2017-01-17 3 views
2

В моей главной форме я реализовал этот код ..Передача несколько SqlParameter методы

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); 
} 

И в моем 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; 
} 

То, что я пытаюсь сделать, это избежать многочисленных

SqlParameter sqlParam = new SqlParameter() 

в моем коде, я попытался так много решений этой проблемы, но я не получил правильный ответ. Я также пытался исследовать это, но я все еще не мог получить правильный ответ.

Пожалуйста, не возражайте против моего соглашения об именах и других кодов, поскольку я намеренно меняю многие из них :) Спасибо.

+0

Почему вы хотите, чтобы избежать этого? Чего вы пытаетесь достичь именно? –

+0

Вы можете создавать параметры с помощью параметра «Parameters.Add», но ваш код явно указывается * для передачи отдельных параметров 'executeStoredProc'. Это немного противоречиво. Почему вы хотите избежать нескольких параметров? –

+0

Попробуйте создать отдельный класс для доступа к данным, в котором вы возвращаете только результат SqlDataAdapter (DataTable, DataSet). Вы можете заставить методы уровня доступа к данным принимать параметры SqlCommand таким образом, чтобы избежать множественных параметров Sql. Вы можете проверить ответ на этот вопрос, я написал простой DAL-> http://stackoverflow.com/questions/25816609/checking-user-name-or-user-email-already-exists/25817145#25817145. Вы можете использовать его. Также в текущем формате вопрос слишком широк. – mybirthname

ответ

2

В качестве альтернативы вашему решению попробуйте использовать уже существующий, используя Dapper (https://github.com/StackExchange/dapper-dot-net).

Вам по-прежнему необходимо использовать несколько параметров, если вам нужна его хранимая процедура или запрос, но это красиво абстрагируется для вас, и это определенно уменьшит количество кода.

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); 
    } 
} 
+1

Он должен быть' Query' не 'Execute' –

+0

@Panagiotis Kanavos, исправлено ... спасибо – vidriduch

0

Отделить базы данных логики в одном месте (поставить sqladapter, SqlCommand и т.д. в одном месте), затем инкапсулировать параметры в вашей команде, как указано ниже, и вам не нужно объявлять SqlParameter отдельно, добавить его в список параметров ,

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

Посмотрите на полный пример ниже

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; 
} 
+0

Ваш код * * создает новые параметры. –

+0

Да, но это по-другому. –

0

Вы можете быть в состоянии использовать SqlParameter Constructor (String, Object). Заменить:

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

С:

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

Однако, делая это вряд ли сделает ваш код быстрее, но уменьшит читаемость.

1

Прежде всего, самым простым вариантом было бы использовать микрофон, такой как Dapper, и получить строго типизированную коллекцию. Gridviews может связываться с чем угодно, включая строго типизированные коллекции. Все это код мог бы стать:

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; 
} 

Даже при использовании сырых ADO.NET, вы можете создать SqlParameter в одной строке с помощью appropriate constructor. Например, вы можете создать новый параметр nvarchar(n) с:

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

или

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

Лучшая идея, хотя это создать объект SqlCommand только один раз и использовать его.Если у вас есть инициализирован объект 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()) 
    { 
    //... 
    } 
} 

Вы можете сделать то же самое с SqlDataAdapter, в том, что, как Windows Forms и данных Адаптеры предназначены для использования с .NET 1.0.

Вместо того, чтобы создавать новый, каждый раз, когда вы хотите заполнить свою сетку, создайте один и повторно используйте его, установив соединение и параметры перед выполнением. Вы можете использовать SqlDataAdapter(SqlCommand) конструктор, чтобы сделать вещи немного чище:

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

И называть это так:

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; 
} 
Смежные вопросы