获取“无法在Null值上调用此方法或属性”错误

时间:2012-02-22 15:40:37

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

更新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值,因为上面的代码是一个精简版本。

任何人都知道如何解决这个问题?

5 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:2)

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

如果MyInt在数据库中可为空并且您具有此实体:

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

您将获得异常:System.Data.SqlTypes.SqlNullValueException:'数据为空。不能在Null值上调用此方法或属性。'

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

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

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

答案 2 :(得分: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));

答案 3 :(得分:0)

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

以下是指向此手册页的链接:IsNull MSDN reference

基本上,您将SQL文本更改为与此类似:

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

现在如果DB中的列为null,它将返回一个空字符串。

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

祝你好运!

答案 4 :(得分:0)

我希望这会有所帮助:

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

我想在将列设置为可空并且具有默认值时,如果不在INSERT SQL中显式引用该列,则在创建新行时不会添加默认值。

由于该错误从未指定在大表中真正可以引起您注意的列名,因此我只是打开最新的行并查找具有Null值的位列。然后,我更改代码以在创建新行时向该列显式添加“ 0”。并手动更改有问题的列。 (在很多行上可能会更难一些。)

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

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