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.
Was ist der genaue Wortlaut der Warnungen:
Es kann mit unterdrückt werden? – demize
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. –
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. –