2012-06-15 6 views
5

Das Problem besteht darin, dass die VS2010-Codeanalyse zwei CA2000-Warnungen für eine bestimmte Funktion zurückgibt. Es ist mir nicht gelungen, die Warnungen mit einem kleineren Codeblock zu reproduzieren, daher habe ich die ursprüngliche Funktion in ihrer Gesamtheit veröffentlicht.CA2000-Warnung, die entfernt werden kann, indem scheinbar unzusammenhängender Code ausgegeben wird

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

Die beiden CA2000 Warnungen beziehen sich auf die Verwendung von Aussagen über die SqlConnection und SqlCommand enthält.

Ich kann keine Probleme in dem Code selbst finden, aber ich habe festgestellt, dass durch das zufällige Auskommentieren von Zeilen die Fehler verschwinden werden. Wenn Sie beispielsweise die drei Geldfelder, die im Block else auf 0 gesetzt sind, auskommentieren, werden die Warnungen entfernt. Wenn Sie am Ende nur die drei Zeilen mit DBNull.Value auskommentieren, wird der Fehler ebenfalls entfernt. Ich kann die Ergebnisse nicht verstehen.

+1

Was ist der genaue Wortlaut der Warnungen:

Es kann mit unterdrückt werden? – demize

+0

Warnung 1: Rufen Sie in der Methode 'Provider.SaveTransaction (Transaction, UserAccount)' System.IDisposable.Dispose für das Objekt 'conn' auf, bevor alle Verweise darauf außerhalb des Gültigkeitsbereichs liegen. –

+0

Warnung 2: Rufen Sie in der Methode "Provider.SaveTransaction (Transaction, UserAccount)" System.IDisposable.Dispose für das Objekt "cmd" auf, bevor alle Verweise darauf nicht im Gültigkeitsbereich enthalten sind. –

Antwort

4

Dies wurde unter Microsoft Connect als möglicher Fehler im Analysator gemeldet. Offensichtlich, wenn eine using Anweisung viel Code enthält, wird diese Nachricht fälschlicherweise gemeldet.

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