Проблема в том, что VS2010 Code Analysis возвращает два предупреждения CA2000 для определенной функции. Мне не удалось воспроизвести предупреждения с меньшим блоком кода, поэтому я разместил исходную функцию целиком.
public int SaveTransaction( Transaction tx, UserAccount account ) {
if ( tx == null ) {
throw new ArgumentNullException( "tx" );
}
if ( account == null ) {
throw new ArgumentNullException( "account" );
}
bool isRefund = tx.TransactionType == LevelUpTransaction.TransactionTypes.Refund;
int pnRef = 0;
using ( SqlConnection conn = new SqlConnection( DatabaseConfiguration.ConnectionString ) ) {
using ( SqlCommand cmd = new SqlCommand( "dbo.SaveTransaction", conn ) ) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add( "@InvoiceId", SqlDbType.VarChar, 100 ).Value = tx.InvoiceNumber;
cmd.Parameters.Add( "@TxStartDate", SqlDbType.DateTime ).Value = tx.TransactionBeginDate;
cmd.Parameters.Add( "@AuthDate", SqlDbType.DateTime ).Value = tx.AuthenticationDate;
cmd.Parameters.Add( "@MerchantKey", SqlDbType.Int ).Value = account.MerchantKey;
cmd.Parameters.Add( "@UserName", SqlDbType.Char, 25 ).Value = account.UserName;
cmd.Parameters.Add( "@RegisterNumber", SqlDbType.Char, 10 ).Value = tx.RegisterNumber;
cmd.Parameters.Add( "@ResellerKey", SqlDbType.Int ).Value = account.ResellerKey;
cmd.Parameters.Add( "@TxEndDate", SqlDbType.DateTime ).Value = tx.TransactionEndDate;
cmd.Parameters.Add( "@IpAddress", SqlDbType.VarChar, 15 ).Value = account.IPAddress;
cmd.Parameters.Add( "@CustomerId", SqlDbType.VarChar, 50 ).Value = tx.CustomerId;
cmd.Parameters.Add( "@TransactionId", SqlDbType.VarChar, 50 ).Value = tx.TransactionId;
cmd.Parameters.Add( "@ProcStartDate", SqlDbType.DateTime ).Value = tx.ProcessorBeginDate;
cmd.Parameters.Add( "@ProcEndDate", SqlDbType.DateTime ).Value = tx.ProcessorEndDate;
cmd.Parameters.Add( "@AuthAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.OriginalAmount );
cmd.Parameters.Add( "@ResultCode", SqlDbType.VarChar, 50 ).Value = tx.ResultCode;
cmd.Parameters.Add( "@ResultMessage", SqlDbType.VarChar, 150 ).Value = tx.ResultMessage;
cmd.Parameters.Add( "@PONumber", SqlDbType.VarChar, 100 ).Value = tx.PurchaseOrderNumber;
cmd.Parameters.Add( "@TaxAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.TaxAmount );
cmd.Parameters.Add( "@Refund", SqlDbType.Bit ).Value = isRefund;
if ( tx.Order != null ) {
cmd.Parameters.Add( "@HostDate", SqlDbType.VarChar, 50 ).Value = tx.Order.HostTime.ToString();
cmd.Parameters.Add( "@ApprovalCode", SqlDbType.VarChar, 50 ).Value = tx.Order.TransactionId.ToString( CultureInfo.InvariantCulture );
cmd.Parameters.Add( "@NameOnCard", SqlDbType.VarChar, 200 ).Value = tx.Order.UserFirstName + " " + tx.Order.UserLastNameInitial;
cmd.Parameters.Add( "@TipAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.Order.Tip.FormattedAmount );
cmd.Parameters.Add( "@TotalAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.Order.TotalAmount.FormattedAmount );
cmd.Parameters.Add( "@DiscountAmount", SqlDbType.Money ).Value = StringParser.ParseDecimal( tx.Order.CreditAmount.FormattedAmount );
}
else {
cmd.Parameters.Add( "@NameOnCard", SqlDbType.VarChar, 200 ).Value = DBNull.Value;
cmd.Parameters.Add( "@HostDate", SqlDbType.VarChar, 50 ).Value = DBNull.Value;
cmd.Parameters.Add( "@ApprovalCode", SqlDbType.VarChar, 50 ).Value = DBNull.Value;
cmd.Parameters.Add( "@TipAmount", SqlDbType.Money ).Value = 0;
cmd.Parameters.Add( "@TotalAmount", SqlDbType.Money ).Value = 0;
cmd.Parameters.Add( "@DiscountAmount", SqlDbType.Money ).Value = 0;
}
if ( isRefund ) {
cmd.Parameters.Add( "@OriginalPnRef", SqlDbType.Int ).Value = tx.OriginalToken;
}
conn.Open();
using ( SqlDataReader dr = cmd.ExecuteReader() ) {
while ( dr.Read() ) {
pnRef = SqlNull.Integer( dr["TRX_HD_Key"] );
}
}
}
}
return pnRef;
}
Два предупреждения CA2000 относятся к операторам using, содержащим SqlConnection
и SqlCommand
.
Я не могу найти никаких проблем в самом коде, но я обнаружил, что случайное комментирование строк приведет к исчезновению ошибок. Например, комментирование трех денежных полей, установленных равным 0 в блоке else
, удалит предупреждения. И наоборот, комментирование только трех строк с помощью DBNull.Значение в конце также удалит ошибку. Я не могу понять результаты.