【问题标题】:Is there an easy way to check multiple columns to see if the value is null?有没有一种简单的方法来检查多个列以查看值是否为空?
【发布时间】:2011-12-06 21:22:28
【问题描述】:

我正在获取参数并从存储过程中获取特定产品。此存储过程返回许多列(我认为大约 15-20)。不幸的是,其中一些值可能为空,当我尝试将它们放入变量时,这当然会产生错误。有没有一种简单的方法来检查这些值是否为NULL,以便它不会引发异常,或者我是否需要在每次分配之前放置if 语句?如果有帮助,这是我的代码:

public List<Product> ReadSpecificProductDetails(string productAndURLID)
    {
        ConfigureDataAccess();
        myCommand = new SqlCommand("[dbo].[GetSpecificProductDetails]", myConnection);
        myCommand.CommandType = CommandType.StoredProcedure;
        //myCommand.Parameters.Add(productAndURLID);
        //myCommand.Parameters.Add(new SqlParameter("@ProductID", SqlDbType.SmallInt));
        myCommand.Parameters.AddWithValue("@ProductID", Convert.ToInt16(productAndURLID));

        try
        {
            try
            {
                myConnection.Open();
                myReader = myCommand.ExecuteReader();
            }
            catch (SqlException exception)
            {
                exception.Data.Add("cstring", myConfiguration);
                throw;
            }
            catch (InvalidOperationException ex)
            {
                ex.Data.Add("cStatus", myConnection.State);
                throw;
            }

            //Create a 'Product' list to store the records in
            while (myReader.Read())
            {
                int productID = Convert.ToInt16(myReader["ProductID"]);
                string productName = (string)myReader["Name"];
                string productNumber = (string)myReader["ProductNumber"];
                //int quantitySum = Convert.ToInt16(myReader["QuantitySum"]);
                string productColor = (string)myReader["Color"];
                int productSafetyStockLevel = Convert.ToInt16(myReader["SafetyStockLevel"]);
                int productReorderPoint = Convert.ToInt16(myReader["ReorderPoint"]);
                decimal productStandardCost = Convert.ToDecimal(myReader["StandardCost"]);
                decimal productListPrice = Convert.ToDecimal(myReader["ListPrice"]);
                string productSize = (string)myReader["Size"];
                decimal productWeight = Convert.ToDecimal(myReader["Weight"]);
                int productDaysToManufacture = Convert.ToInt16(myReader["DaysToManufacture"]);
                string productCategoryName = (string)myReader["PC.Name"];
                string productSubCategoryName = (string)myReader["PS.Name"];
                string productModelName = (string)myReader["PM.Name"];
                DateTime productSellStartDate = Convert.ToDateTime(myReader["Sell_Start_Date"]);
                DateTime productSellEndDate = Convert.ToDateTime(myReader["Sell_End_Date"]);
                DateTime productDiscontinuedDate = Convert.ToDateTime(myReader["Discontinued_Date"]);
                Product p = new Product(productID, productName, productNumber, productColor, productSafetyStockLevel, productReorderPoint, productStandardCost,
                    productListPrice, productSize, productWeight, productDaysToManufacture, productCategoryName, productSubCategoryName, productModelName, productSellStartDate,
                    productSellEndDate, productDiscontinuedDate);
                myProducts.Add(p);
            }
        }
        finally
        {
            myReader.Close();
            myConnection.Close();
        }
        return myProducts;
    }

【问题讨论】:

  • 我强烈建议使用 LINQ-to-SQL 将您的数据库映射到类中,这使得这些事情变得非常简单和容易。

标签: c# asp.net


【解决方案1】:
int? x = dt.Field<int?>( "Field" );

或者

int y = dt.Field<int?>( "Field" ) ?? 0;

C# DBNull and nullable Types - cleanest form of conversion

顶部可能是您最好的方法。您当前正在填充一些不可为空的类型。因此,如果您希望能够将它们表示为 null,请使用顶级方法。否则,您可以使用其他选项来提供默认值。

【讨论】:

  • 我已经结合我的解决方案使用了可空类型。它工作得很好。我已经为它运行了许多单元测试。我也喜欢你的建议。
【解决方案2】:

正如 ssg 在 cmets 中建议的那样,LINQ 将是您在这些情况下最好的朋友,但是如果您想大量添加空值检查,您可以实现以下内容:

int productID = (myReader["ProductID"] != null) ? Convert.ToInt16(myReader["ProductID"]) : 0;

或者您可以简单地使用 if 语句。

【讨论】:

    【解决方案3】:

    对您可能怀疑为空值的字段执行 DBNULL 检查。在这种情况下,所有这些。

    if (! DBNull.Value.Equals(row[fieldName])) 
          return (string) row[fieldName] + " ";
       else
          return String.Empty;
    

    您可以做的是创建一个函数,该函数具有多个用于检查 null 的 int、string 和 DateTime 参数的重载

    所以它看起来像这样:

    public string CheckNull(string value)
    {
       if (! DBNull.Value.Equals(value)) 
              return value;
           else
              return String.Empty;
    }
    

    这样你只需要做类似的事情

    object.stringProperty = (string)CheckNull(row["columnName"]);
    

    【讨论】:

      【解决方案4】:

      当使用数据读取器和 DTO 之间的直接映射时,我使用数据读取器的 IsDbNull() 方法。以下是使用不同数据类型的几个示例:

      myObj.MyStringProperty = !myReader.IsDBNull("myStringColumn") ? myReader["myStringColumn"].ToString() : null;
      myObj.MyNullableDecimalProperty = !myReader.IsDBNull("mydecimalColumn") ? decimal.Parse(myReader["mydecimalColumn"].ToString()) : new decimal?();
      

      【讨论】:

        猜你喜欢
        • 2021-06-27
        • 2011-08-08
        • 2012-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-03
        • 2017-06-21
        • 1970-01-01
        相关资源
        最近更新 更多