C#我应该在这里演出什么类型?

时间:2018-02-15 09:16:35

标签: c# types nullable

我有一部分代码可以通过从数据库中读取所有先前的费用和付款来计算新的余额,然后将新的金额添加到余额中。它可以很好地处理我手工种植到数据库中的值,但是当我擦除所有测试值并从头开始时,我开始遇到错误。

这是代码:

        //sum all prior charges
        try
        {
            connection.Open();
            command.Connection = connection;

            command.CommandText = "SELECT SUM(Amount) FROM Charges WHERE TransactionDate<='" + DateTime.Now + "';";
            chargesSoFar = (double)command.ExecuteScalar();
            connection.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }

        // sum all prior payments
        try
        {
            connection.Open();
            command.Connection = connection;

            command.CommandText = "SELECT SUM(Amount) FROM Payments WHERE TransactionDate<='" + DateTime.Now + "';";
            paymentsSoFar = (double)command.ExecuteScalar();
            connection.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }

        // calculate balance
        tempCharge.Balance = (decimal)(chargesSoFar + int.Parse(textBoxAmount.Text) - paymentsSoFar);

        DataWriter.WriteCharge(tempCharge);

我得到的错误是类型转换错误,我在其中转换了ExecuteScalar结果。发生错误是因为没有先前的费用或付款,因此返回null,在转换为double时失败。

我可以投射另一种类型,然后我可以检查它是否为空?如果没有,我该如何解决这个问题?

感谢任何帮助。如果我不清楚我在这里想做什么,请问任何问题。

3 个答案:

答案 0 :(得分:4)

尝试nullable数据类型:

add_action( 'template_redirect', 'set_default_variation_job' );
function set_default_variation_job() {
    if ( ! is_product() || is_admin() ) return;

    global $wpdb, $post;

    // Get an instance of the WC_Product object
    $product = wc_get_product($post->ID);
    $product_id = $post->ID;

    // Check if default variation has been updated, if yes we exit
    if( get_post_meta( $product_id, '_default_variation_updated', true ) ) return;

    // Only for variable products
    if ( $product->is_type( 'variable' ) ) {

        $max_price = $product->get_variation_price('max', true); // Get Max variation price

        // SQL Query: Get the variation ID of the  max variation price
        $result = $wpdb->get_col("
            SELECT pm.post_id FROM {$wpdb->prefix}postmeta as pm
            INNER JOIN {$wpdb->prefix}posts as p ON pm.post_id = p.ID
            WHERE p.post_type LIKE 'product_variation' AND p.post_parent = $product_id
            AND pm.meta_key LIKE '_price' and pm.meta_value = $max_price
        ");
        $variation_id= reset($result); // get the first variation ID as a string

        // Get an instance of the WC_Product_Variation object
        $variation = wc_get_product($variation_id);
        $default_attributes = array();

        // Loop through this variation attributes and format them
        foreach( $variation->get_variation_attributes() as $key => $value ){
            $taxonomy = str_replace( 'attribute_', '', $key );
            $default_attributes[ $taxonomy ] = $value;
        }

        // Set the default variation attributes in the Variable product
        $product->set_default_attributes( $default_attributes );
        // Set a meta data flag to avoid update repetitions
        update_post_meta( $product_id, '_default_variation_updated', '1' );
        $product->save(); // Save the data
    }
}

作为旁注,参数化查询很可能是防止sql注入的最佳实践。为此,

double? chargesSoFar = null;
// other codes here
chargesSoFar = (double?)command.ExecuteScalar();

根据这个问题:What is the best data type to use for money in c#?

要使用的最佳数据类型是十进制。

try
{
    connection.Open();
    command.Connection = connection;

    command.CommandText = "SELECT SUM(Amount) FROM Payments WHERE TransactionDate <= @TransData;";
    command.Parameter.AddWithValue("TransData", DateTime.Now);
    chargesSoFar = (double?)command.ExecuteScalar();
    connection.Close();
}
catch (Exception ex)
{
    MessageBox.Show("Error: " + ex.Message);
}

答案 1 :(得分:1)

你可以使用问号后缀强制转换为可空类型,即(double?),然后你可以检查null。

dplyr

也阅读SQL注入:https://www.acunetix.com/websitesecurity/sql-injection/,因为您的代码目前容易受到此类攻击

答案 2 :(得分:1)

也许你可以转发Nullable<double>double?

double? paymentsSoFar = (double?)command.ExecuteScalar();

if(paymentsSoFar.HasValue)
{
    // Then its safe to calculate 

    double myActualValue = paymentsSoFar.Value;
}

Nullable Types (C# Programming Guide)

  

可空类型具有以下特征:

     
      
  • Nullable类型表示可以赋值null的值类型变量。您无法基于a创建可空类型   参考类型。

  •   
  • 语法T?Nullable<T>的简写,其中T是值类型。这两种形式是可以互换的。

  •   
  • 将值分配给可空类型,就像使用普通值类型一样,例如int? x = 10;double? d = 4.108。可空的   type也可以赋值null:int? x = null

  •   
  • 使用Nullable<T>.GetValueOrDefault方法返回指定的值,或者返回基础类型的默认值(如果   value为null,例如int j = x.GetValueOrDefault();

  •   
  • 使用HasValue和Value只读属性来测试null并检索值,如以下示例所示:   if(x.HasValue) j = x.Value;

  •   
  • 如果变量包含值,则HasValue属性返回true;如果是false,则返回null

  •   
  • 如果指定了一个值,则Value属性返回一个值。否则,抛出System.InvalidOperationException

  •   
  • HasValue的默认值为false。 Value属性没有默认值。

  •   
  • 您还可以使用可为空类型的==!=运算符,如以下示例所示:if (x != null) y = x;

  •   
  • 使用??运算符指定当当前值为null的可空类型分配给a时将应用的默认值   非可空类型,例如int? x = null; int y = x ?? -1;

  •   
  • 不允许使用嵌套的可空类型。以下行不会编译:{{1​​}}

  •