Смущен из-за перегрузки метода - PullRequest
1 голос
/ 08 ноября 2010

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

Я хочу вставить некоторые данные в свою базу данных 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, executeGrade, 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

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

ОБНОВЛЕНИЕ

Я изменил свою функцию так, чтобы дополнительные параметры были внизу.Вот так:

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

Ответы [ 7 ]

5 голосов
/ 08 ноября 2010

В C # 4.0 вы можете использовать необязательные параметры в сочетании с обнуляемыми типами :

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

При таком количестве параметров вы можете рассмотреть возможность рефакторинга вводить параметр объекта *1009* - это облегчит чтение и изменение вашего кода в будущем.

3 голосов
/ 08 ноября 2010

Я бы создал struct для инкапсуляции параметров.

Вот возможные варианты, о которых я мог бы подумать:

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

Надеюсь на помощь

1 голос
/ 08 ноября 2010

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

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); вместо всех этих операторов if.

0 голосов
/ 08 ноября 2010

Похоже, вы используете Visual Studio 2010, C # 4.0, поэтому теперь они вводят необязательные параметры: http://msdn.microsoft.com/en-us/library/dd264739.aspx

0 голосов
/ 08 ноября 2010

другим способом может быть использование необязательных параметров

0 голосов
/ 08 ноября 2010

См. Ссылку на типы, допускающие обнуление: 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
    )
0 голосов
/ 08 ноября 2010

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

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