【问题标题】:Getting "This method or property cannot be called on Null values" error获取“无法在 Null 值上调用此方法或属性”错误
【发布时间】:2012-03-12 23:13:24
【问题描述】:

更新 1:

在这一行抛出异常:

client_group_details.Add(new ClientGroupDetails(

原始问题:

我有以下代码,我已将数据库中的 30 列数据精简为数据库中的 2 列。每当任何列返回 NULL 值时,我都会收到错误:

public class ClientGroupDetails
{
    public String Col2;
    public String Col3;

    public ClientGroupDetails(String m_Col2, String m_Col3)
    {
        Col2 = m_Col2;
        Col3 = m_Col3;
    }

    public ClientGroupDetails() { }
}

[WebMethod()]
public List<ClientGroupDetails> GetClientGroupDetails(string phrase)
{
    var client_group_details = new List<ClientGroupDetails>();

    using (connection = new SqlConnection(ConfigurationManager.AppSettings["connString"]))
    {
        using (command = new SqlCommand(@"select col2, col3 where col1 = @phrase", connection))
        {
            command.Parameters.Add("@phrase", SqlDbType.VarChar, 255).Value = phrase;

            connection.Open();
            using (reader = command.ExecuteReader())
            {
                int Col2Index = reader.GetOrdinal("col2");
                int Col3Index = reader.GetOrdinal("col3");

                while (reader.Read())
                {
                    client_group_details.Add(new ClientGroupDetails(
                        reader.GetString(Col2Index),
                        reader.GetString(Col3Index)));
                }
            }
        }
    }

    return client_group_details;
}

我得到的错误是:

数据为空。不能对 Null 值调用此方法或属性。

我不确定如何处理 NULL 值,因为上面的代码是精简版。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 代码的哪一行导致异常被抛出?异常的类别是什么(例如ArgumentNullException)?
  • 看来你不是第一个得到这种异常并发布它的人。有人在使用 TFS 时发现了这种问题,具体的异常类型是SqlNullValueException(参见social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/…)。
  • 这不是数据库意义上的NULL。这是一个null,表示引用没有价值。您看到的确切异常是什么? ArgumentNullException?
  • 我在client_group_details.Add(new ClientGroupDetails(上遇到了异常

标签: c# .net-3.5 c#-3.0 asmx asp.net-3.5


【解决方案1】:

在调用GetString之前,您需要使用 IsDbNull 检查列是否为空,例如:

string s1, s2;

if (reader.IsDbNull(Col1Index) == false)
{
   s1 = reader.GetString(Col1Index);
}

if (reader.IsDbNull(Col2Index) == false)
{
   s2 = reader.GetString(Col2Index);
}

client_group_details.Add(new ClientGroupDetails(s1, s2));

【讨论】:

    【解决方案2】:

    有几种方法可以做到这一点,但我认为代码的最佳方法是在 SQL 文本中添加一个简单的函数调用 - 即 IsNull 函数。

    这里是此手册页的链接:IsNull MSDN reference

    基本上,您会将 SQL 文本更改为如下所示:

    "select IsNull(col2, ''), IsNull(col3, '') where col1 = @phrase"
    

    现在如果数据库中的列为空,它将改为返回一个空白字符串。

    您还可以在列上设置默认值,或者您可以在代码端检查System.DBNull.Value

    祝你好运!

    【讨论】:

      【解决方案3】:

      这是因为不应在 DBNull 值上调用 reader.GetString。尝试如下更改您的代码:

      client_group_details.Add(new ClientGroupDetails(
          reader.IsDbNull(Col2Index) ? null : reader.GetString(Col2Index),
          reader.IsDbNull(Col3Index) ? null : reader.GetString(Col3Index)));
      

      【讨论】:

        【解决方案4】:

        如果您尝试从数据库中读取一些可为空的数据,但您的类型不可为空,您可能会收到此错误。

        如果 MyInt 在数据库中可以为空并且你有这个实体:

        public class MyEntity
        {
            public int Id { get; set; }
            public int MyInt { get; set; }
        }
        

        你会得到异常:System.Data.SqlTypes.SqlNullValueException: 'Data is Null.不能对 Null 值调用此方法或属性。'

        要解决此问题,只需将 MyInt 属性的类型更改为 Nullable 或 int?:

        public class MyEntity
        {
            public int Id { get; set; }
            public int? MyInt { get; set; }
        }
        

        注意:这不是对原始问题的回答,而是对标题中问题的回答。

        【讨论】:

          【解决方案5】:

          我希望这会有所帮助:

          向现有表添加新列时,如果它是位列(布尔值),我将 SQL Server 2019 中的默认值设置为“(0)”(false),并将列设为 Nullable。

          我猜当使列可以为空并且具有默认值时,如果没有在 INSERT SQL 中显式引用该列,则在创建新行时不会添加默认值。

          由于该错误从未指定在大表中真正让您眼花缭乱的列名,因此我只打开最新的行并查找具有 Null 值的位列。然后我更改我的代码以在创建新行时显式地将“0”添加到该列。并手动更改违规列。 (在很多行上可能会更难一些)。

          这是一种解决方案,但理想的解决方案是返回并将列定义设为“Not Null”。

          还有一个解决方案可能是在我的 .NET Core 2.2 Razor Pages 应用程序中更改模型。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-07-20
            • 2012-03-31
            • 2023-04-06
            • 1970-01-01
            • 1970-01-01
            • 2022-10-31
            • 2020-09-21
            • 1970-01-01
            相关资源
            最近更新 更多