2012-06-15 30 views
5

问题是VS2010代码分析针对特定功能返回两个CA2000警告。我还没有成功用较小的代码块复制警告,所以我已经完整地发布了原始函数。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警告涉及含有SqlConnectionSqlCommand using语句。

我在代码本身找不到任何问题,但我发现随机发表评论会使错误消失。例如,注释else区块中的三个货币字段设置为0将删除警告。相反,在最后用DBNull.Value注释掉三行也会删除错误。我无法理解结果。

+1

有什么警告的确切的文本? – demize

+0

警告1:在方法'Provider.SaveTransaction(Transaction,UserAccount)'中,在对象'conn'上调用System.IDisposable.Dispose之前,所有对它的引用超出范围。 –

+0

警告2:在方法'Provider.SaveTransaction(Transaction,UserAccount)'中,在对象'cmd'上调用System.IDisposable.Dispose之前,所有对它的引用超出范围。 –

回答

4

这已报告在Microsoft Connect作为分析仪中可能的错误。显然,如果一个using声明包含很多代码,则会错误地报告此消息。

它可以与抑制:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]