2010-11-08 2 views
1

Я использую .NET 4.0 с ASP.NET 4.0 и C# (это будет C# 4.0?).Confused о перегрузке метода

Я хочу, чтобы вставить данные в моей базе данных SQL Server и у меня есть метод, как и справиться с этим:

public int InsertTrade(
    string symbol, 
    string tradeSetupId, 
    int tradeTypeId, 
    decimal lotsPerUnit, 
    string chartTimeFrame, 
    int tradeGrade, 
    int executionGrade, 
    int MFEPips, 
    int MAEPips, 
    decimal pctAccountRisked 
    ) 
{ 
    SqlCommand cmd = new SqlCommand("usp_InsertTrade"); 
    cmd.Parameters.AddWithValue("@symbol", symbol); 
    cmd.Parameters.AddWithValue("@pctAccountRisked", pctAccountRisked); 
    cmd.Parameters.AddWithValue("@tradeSetupId", tradeSetupId); 
    cmd.Parameters.AddWithValue("@lotsPerUnit", lotsPerUnit); 
    cmd.Parameters.AddWithValue("@tfCode", chartTimeFrame); 
    cmd.Parameters.AddWithValue("@MAEPips", MAEPips); 
    cmd.Parameters.AddWithValue("@MFEPips", MFEPips); 
    cmd.Parameters.AddWithValue("@tradeGrade", tradeGrade); 
    cmd.Parameters.AddWithValue("@executionGrade", executionGrade); 
    return (InsertData(cmd, "trade")); 
} 

Есть несколько нетребуемые полей: tradeGrade, executionGrade, MFEPips, MAEPips. Хранимая процедура usp_InsertTrade предоставляет эти необязательные параметры как NULLable. Каков наилучший способ кодировать это в C#? Я учусь программировать, поэтому было бы здорово, если бы вы могли предложить рекомендации по лучшей практике.

Вот сохраненные параметры процедуры для usp_InsertTrade:

CREATE procedure [dbo].[usp_InsertTrade] 
@symbol char(6), 
@tradeSetupId varchar(10), 
@tradeTypeId int, 
@lotsPerUnit decimal(18,1), 
@chartTimeFrame varchar(5), 
@tradeGrade smallint = NULL, 
@executionGrade smallint = NULL, 
@MFEPips int = NULL, 
@MAEPips int = NULL, 
@pctAccountRisked decimal(3,2) 
AS 

Большое спасибо.

UPDATE

Я изменил свою функцию, так что дополнительные параметры находятся в нижней части. Как так:

public int InsertTrade(
    string symbol, 
    string tradeSetupId, 
    int tradeTypeId, 
    decimal lotsPerUnit, 
    string chartTimeFrame, 
    decimal pctAccountRisked, 
    int? tradeGrade, 
    int? executionGrade, 
    int? MFEPips, 
    int? MAEPips 
    ) 
{ 
    SqlCommand cmd = new SqlCommand("usp_InsertTrade"); 
    // required parameters 
    cmd.Parameters.AddWithValue("@symbol", symbol); 
    cmd.Parameters.AddWithValue("@tradeSetupId", tradeSetupId); 
    cmd.Parameters.AddWithValue("@tradeTypeId", tradeTypeId); 
    cmd.Parameters.AddWithValue("@lotsPerUnit", lotsPerUnit); 
    cmd.Parameters.AddWithValue("@tfCode", chartTimeFrame); 
    cmd.Parameters.AddWithValue("@pctAccountRisked", pctAccountRisked); 

    // optional parameters 
    if (MAEPips.HasValue) 
     cmd.Parameters.AddWithValue("@MAEPips", MAEPips); 
    if (MFEPips.HasValue) 
     cmd.Parameters.AddWithValue("@MFEPips", MFEPips); 
    if (tradeGrade.HasValue) 
     cmd.Parameters.AddWithValue("@tradeGrade", tradeGrade); 
    if (executionGrade.HasValue) 
     cmd.Parameters.AddWithValue("@executionGrade", executionGrade); 
    return (InsertData(cmd, "trade")); 
} 

Когда я вызвать функцию, используя этот код:

DBUtil DB = new DBUtil(); 
int tradeId = DB.InsertTrade (
    ddlSymbols.SelectedValue, 
    ddlTradeSetups.SelectedValue, 
    ddlTradeTypes.SelectedValue, 
    decimal.Parse(txtLotsPerUnit.Text), 
    ddlTimeFrames.Text, 
    decimal.Parse(txtAcctRisk.Text)); 

Я получаю эту ошибку:

No overload for method 'InsertTrade' takes 6 arguments 
+0

вы не указали в объявлении параметра = null - это вызывает вашу ошибку. – Paddy

+0

@Paddy - спасибо, нужен кофе ... –

+0

Кроме того, я думаю, вам, возможно, понадобится указать null в ваш тип с нулевым значением. Например; 'Int? сделкаGrade = (int?) null'. –

ответ

5

С C# 4.0, вы можете использовать optional parameters в с nullable types:

public int InsertTrade(
    string symbol, 
    string tradeSetupId, 
    int tradeTypeId, 
    decimal lotsPerUnit, 
    string chartTimeFrame, 
    decimal pctAccountRisked, 
    int? tradeGrade = null, 
    int? executionGrade = null, 
    int? MFEPips = null, 
    int? MAEPips = null 
    ) 
{ 
    SqlCommand cmd = new SqlCommand("usp_InsertTrade"); 
    cmd.Parameters.AddWithValue("@symbol", symbol); 
    cmd.Parameters.AddWithValue("@pctAccountRisked", pctAccountRisked); 
    cmd.Parameters.AddWithValue("@tradeSetupId", tradeSetupId); 
    cmd.Parameters.AddWithValue("@lotsPerUnit", lotsPerUnit); 
    cmd.Parameters.AddWithValue("@tfCode", chartTimeFrame); 
    if(MAEPips.HasValue) 
     cmd.Parameters.AddWithValue("@MAEPips", MAEPips); 
    if(MFEPips.HasValue) 
     cmd.Parameters.AddWithValue("@MFEPips", MFEPips); 
    if(tradeGrade.HasValue) 
     cmd.Parameters.AddWithValue("@tradeGrade", tradeGrade); 
    if(executionGrade.HasValue) 
     cmd.Parameters.AddWithValue("@executionGrade", executionGrade); 
    return (InsertData(cmd, "trade")); 
} 

С помощью этого большого количества параметров вы можете рассмотреть рефакторинг introduce parameter object - это сделает ваш код более легким для чтения и изменения в будущем.

+0

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

+0

@Mark Allison - вы сделали свои параметры _nullable_ only ('int? MFEPips,'). Я также сделал их _optional_ ('int? MFEPips = null,'). См. Дополнительные '= null'? – Oded

+0

спасибо, отлично работает сейчас. Мне нужно пойти и провести некоторое исследование объекта объекта параметра, о котором вы говорили. –

0

Вы можете использовать NULLABLE значения параметров и проверьте значение перед добавлением параметра, таким образом, он будет использовать сохраненное значение proc по умолчанию, если значение не указано:

public int InsertTrade(
    ... 
    int? executionGrade, 
    ... 
    ) 
{ 
    SqlCommand cmd = new SqlCommand("usp_InsertTrade"); 
    ... 
    if(executionGrade.HasValue) 
     cmd.Parameters.AddWithValue("@executionGrade", executionGrade); 
    return (InsertData(cmd, "trade")); 
} 
+0

Несомненно, ему не нужно проверять, имеет ли он значение, поскольку оно будет передано прямо в Хранимую процедуру, ноль или иначе? –

+0

@ Moo-Juice SQL 'NULL' - это отличная вещь от C#' null'. Чтобы упомянуть SQL 'NULL' в C#, вам нужно сказать' DBNull.Value'. Здесь, поскольку дефолт в определении sproc является 'NULL', как мы хотим, проще всего ничего не сказать. – AakashM

+0

@ Moo-Juice - это то, что даже не добавляя параметр, он использует все, что был выбран разработчиком Stored Proc по умолчанию, что не обязательно является нулевым. – Jamiec

0

Смотрите эту ссылку на обнуляемых типах: http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

Короче говоря, объявить функцию:

public int InsertTrade(
    string symbol, 
    string tradeSetupId, 
    int tradeTypeId, 
    decimal lotsPerUnit, 
    string chartTimeFrame, 
    int? tradeGrade, 
    int? executionGrade, 
    int? MFEPips, 
    int? MAEPips, 
    decimal pctAccountRisked 
    ) 
3

Я хотел бы создать struct, чтобы инкапсулировать параметры.

Вот жизнеспособные пути я мог думать о:

  1. факультативных параметров. Вы можете определить метод с некоторыми необязательными параметрами, используя синтаксис C# 4.0 (эта функция уже присутствовала в VB, но недавно добавлена ​​в C#). Недостаток: вы ограничены тем, как использовать дополнительные параметры. Только последние параметры могут быть сделаны необязательными. Я имею в виду, если у вас есть (имя, адрес, телефон) в качестве параметров, в этом порядке вы не можете пропустить адрес и установить имя
  2. Структура. Как уже упоминалось, это мой любимый способ.Вы можете установить любое пустое значение, но вы должны создать-структуру для каждого метода
  3. Define перегрузок: худший метод для определения перегрузки для каждого комбинации из Params, что неосуществимо с коллекцией больших параметров
  4. объектов массив: возможно, только если все параметры имеют другой тип. Вы можете определить параметр, основываясь на типе каждой записи в массиве объектов.
  5. Dictionary<string,object>: еще один интересный метод. Каждая запись отображается с помощью ключа

Надежда, была помощь

+0

Wow thanks, я не знал, что было так много способов кошки кошки! –

1

Я хотел бы создать метод расширения, чтобы избавиться от повторных проверок по переменным с нулевым значением. Метод расширения будет выглядеть примерно так:

public static class SqlCommandExtensions 
{ 
    public static void AddNullableInParameter<T>(this SqlCommand command, string columnName, Nullable<T> value) where T : struct 
    { 
     if (value.HasValue) 
     { 
      command.Parameters.AddWithValue(columnName, value.Value); 
     } 
    } 
} 

Теперь вы можете просто написать command.AddNullableInParameter("@yourParameter", YourNullableType); вместо всех тех, если заявления.

Смежные вопросы