我正在使用.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,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
非常感谢。
更新
我已经更改了我的功能,以便可选参数位于底部。像这样:
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 :(得分: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重构 - 它将使您的代码在将来更易于阅读和修改。
答案 1 :(得分:3)
我会创建一个struct
来封装参数。
以下是我可能想到的可行方法:
Dictionary<string,object>
:另一种有趣的方法。每个条目都使用密钥映射希望得到帮助
答案 2 :(得分: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语句。
答案 3 :(得分:0)
您可以在参数中使用可为空的值,并在添加参数之前检查值,这样如果未提供该值,它将使用存储过程的默认值:
public int InsertTrade(
...
int? executionGrade,
...
)
{
SqlCommand cmd = new SqlCommand("usp_InsertTrade");
...
if(executionGrade.HasValue)
cmd.Parameters.AddWithValue("@executionGrade", executionGrade);
return (InsertData(cmd, "trade"));
}
答案 4 :(得分: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
)
答案 5 :(得分:0)
另一种方法可能是使用optional parameters
答案 6 :(得分:0)
听起来您正在使用Visual Studio 2010,C#4.0,因此他们现在引入了可选参数:http://msdn.microsoft.com/en-us/library/dd264739.aspx