2010-11-08 85 views
1

我在ASP.NET 4.0和C#中使用.NET 4.0(会不会是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,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 2010-11-08 11:40:43

+0

@Paddy - 谢谢,需要咖啡...... – 2010-11-08 11:44:41

+0

另外,我认为你可能需要将空值转换为空值类型。例如; '诠释? tradeGrade =(int?)null'。 – 2010-11-08 11:46:12

回答

5

在C#4.0中,你可以使用optional parametersnullable 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

谢谢,请你看看我的问题的更新部分?我收到一个错误,我不知道为什么。 – 2010-11-08 11:38:51

+0

@Mark Allison - 您已将参数设置为_nullable_ only('int?MFEPips,')。我也将它们设置为_optional_('int?MFEPips = null,')。看到额外的'= null'? – Oded 2010-11-08 11:42:31

+0

谢谢,现在工作很好。我将不得不去研究你所谈论的参数对象。 – 2010-11-08 11:45:41

0

你可以在参数中使用空的值,并检查在添加参数之前的值,这样,如果未提供该值,它将使用存储的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

当然,他不需要检查它是否有价值,因为它会直接传递给存储过程,为空或以其他方式? – 2010-11-08 11:03:37

+0

@ Moo-Juice SQL'NULL'与C#'null'是不同的东西。要在C#中提到一个SQL'NULL',你需要说'DBNull.Value'。在这里,由于我们想要的存储区定义中的默认值是'NULL',最简单的事情就是不说任何话。 – AakashM 2010-11-08 11:08:31

+0

@ Moo-Juice - 其中的特点是,即使不添加参数,它也会使用Stored Proc开发人员选择的任何内容作为默认参数 - 不一定为null。 – Jamiec 2010-11-08 11:28:16

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. 结构。如前所述,这是我最喜欢的方式。您可以设置任何空值,但是你必须创建一个struct每种方法
  3. 定义重载:最坏的方法是定义一个过载每个组合则params的,这是不可行的大参数集合
  4. 对象数组:仅在全部参数具有不同类型时才可行。您可以根据对象数组中的每个条目的类型确定参数。
  5. Dictionary<string,object>:另一个有趣的方法。每个条目映射用钥匙

希望能一直帮助

+0

哇,谢谢,我不知道有这么多方法去皮肤猫! – 2010-11-08 11:09:28

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);代替所有的if语句的。