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

本文关键字:Null 此方法 值调用 属性 不能 数据 | 更新日期: 2023-09-27 18:27:57

我正在开发一个应用程序,可以从数据库中获取电影信息,还可以添加、更新和删除电影。在数据库中,我有三个表(Movie、Genre和MovieGenre<-存储电影及其类型)。除了一件事之外,一切都很好,那就是一部电影没有任何类型(这应该是可能的)。

以下方法中出现问题,并引发以下异常:数据为Null。不能对Null值调用此方法或属性

原因(当然)是存储过程返回null,因为电影没有任何类型,但我不知道如何防止抛出此异常。正如我所说,应该可以在不存储任何类型信息的情况下存储电影。

方法:

public List<MovieGenre> GetMovieGenrebyMovieID(int movieID) {
    using (SqlConnection conn = CreateConnection()) {
        try {
            SqlCommand cmd = new SqlCommand("dbo.usp_GetMovieGenreByMovieID", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@MovieID", movieID);
            List<MovieGenre> movieGenre = new List<MovieGenre>(10);
            conn.Open();
            using (SqlDataReader reader = cmd.ExecuteReader()) {
                int movieGenreIDIndex = reader.GetOrdinal("MovieGenreID");
                int movieIDIndex = reader.GetOrdinal("MovieID");
                int genreIDIndex = reader.GetOrdinal("GenreID");
                while (reader.Read()) {
                    movieGenre.Add(new MovieGenre {
                        MovieID = reader.GetInt32(movieIDIndex),
                        MovieGenreID = reader.GetInt32(movieGenreIDIndex),
                        GenreID = reader.GetInt32(genreIDIndex)
                    });
                }
            }
            movieGenre.TrimExcess();
            return movieGenre;
        }
        catch {
            throw new ApplicationException();
        }
    }
}

存储过程:

ALTER PROCEDURE usp_GetMovieGenreByMovieID
@MovieID int
AS
BEGIN
    BEGIN TRY
        SELECT m.MovieID, g.GenreID, mg.MovieGenreID, g.Genre
        FROM Movie AS m
        LEFT JOIN MovieGenre AS mg
            ON m.MovieId = mg.MovieID
        LEFT JOIN Genre AS g
            ON mg.GenreID = g.GenreID
        WHERE m.MovieID = @MovieID
    END TRY
    BEGIN CATCH
        RAISERROR ('Error while trying to receive genre(s).',16,1)
    END CATCH
END

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

您不应该试图将proc中的null值转换为int,因此在创建MovieGenre实例之前,您需要使用SqlDataReader.IsDBNull方法检查可为null的字段:

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.isdbnull.aspx

假设GenreID和MovieGenreID是可以为null的int,您可以执行以下操作:

movieGenre.Add(new MovieGenre {
  MovieID = reader.GetInt32(movieIDIndex),
  MovieGenreID = reader.IsDBNull(movieGenreIDIndex) ? null : reader.GetInt32(movieGenreIDIndex),
  GenreID = reader.IsDBNull(genreIDIndex) ? null : reader.GetInt32(genreIDIndex)
});

此错误发生在我在实体框架核心3.1项目中启用C#8可为null的功能之后。

解决方案是将实体属性更改为可为null的对应属性。例如,

更改自:

public class Person {
  public int Id { get; set; }
  public string Name { get; set; }
  public string Address { get; set; }
}

收件人:

public class Person {
  public int Id { get; set; }
  public string Name { get; set; }
  public string? Address { get; set; }  // change 'Address' to nullable string since it is nullable in database
}

在我的案例中,我使用的是EF Core,问题是该字段在数据库中可以为null,但在ModelCreating中,它是这样要求的:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<MyEntity>(entity =>
   {
      entity.Property(e => e.Details)
                    .IsRequired()
                    .HasMaxLength(250);
   }
}

我删除了IsRequired(),它运行良好。

几天后更新,得到了同样的问题,一个字符串字段它不允许在数据库中为null。

如下编辑您的选择语句以处理null问题。

SELECT ISNULL(m.MovieID,0) AS MovieID, 
       ISNULL(g.GenreID,0) AS GenreID, 
       ISNULL(mg.MovieGenreID,0) AS MovieGenreID,
       ISNULL(g.Genre,'') AS Genre
FROM --rest of your query...

我意识到这是旧的,但我刚刚在.net 6中为EF Core遇到了这个问题。

尽管字符串可以为null,实体框架甚至从具有字符串类型的现有表中创建了我的对象,但我必须将字符串列的类型更改为字符串?键入,以便取回数据为null的数据。

错误:

public string Decision { get; set; }

正确:

public string? Decision { get; set; }

我以为我在依赖项注入方面遇到了问题。原来是实体框架核心,这是一个简单的修复。

我在.net5数据优先项目中遇到了这个问题,因为数据库中的一个字段是可以为null的,但在c#实体类中是必需的。通过efcorepowertools扩展重新创建实体后,问题得到了解决。

最简单的答案是用非null值替换null。尝试:

ALTER PROCEDURE usp_GetMovieGenreByMovieID
@MovieID int
AS
BEGIN
    BEGIN TRY
        SELECT m.MovieID, 
               coalesce(g.GenreID,0) GenreID, 
               coalesce(mg.MovieGenreID,0) MovieGenreID, 
               coalesce(g.Genre, 'Not Applicable') Genre
        FROM Movie AS m
        LEFT JOIN MovieGenre AS mg
            ON m.MovieId = mg.MovieID
        LEFT JOIN Genre AS g
            ON mg.GenreID = g.GenreID
        WHERE m.MovieID = @MovieID
    END TRY
    BEGIN CATCH
        RAISERROR ('Error while trying to receive genre(s).',16,1)
    END CATCH
END

如果有人遇到过这个问题,下面是我的案例。

我正在构建WEB Api。在我放置[必需]Attribue之前-https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute?view=net-5.0,我的数据库中有一些NULL值。然后我将这个属性添加到我的模型中,并试图发出GET请求,但";System.InvalidOperationException:数据在序号1处为NULL。不能对NULL值调用此方法。调用之前请使用IsDBNull进行检查"出现。

所以我从数据库中删除了NULL值,之后每个请求都能正常工作据我所知,发生错误是因为EF Core在应用[Required]属性时不允许在数据库中使用NULL值。

我希望这对某人有帮助。

今天我遇到了这个问题。但我的问题已经用另一种方式解决了。如果有一天有人绊倒了,答案就在他们身上。

由于这是一个通用的C#.NET CLI异常

我在一个没有默认值的DB表中添加了一个新的外键。因此,该值被设置为NULL,因为该列被设置为允许null。我在查询那张表时遇到了这个异常。

作为解决方案,我用适当的值替换了NULL值(因为它们是外键,所以应该是适当的)。

仅此而已。

谢谢。

对我来说,之所以发生这种情况,是因为在数据库中,我有一个列"XYZ"的值为NULL,但映射到它的模型属性(bool)不可为NULL。

我也遇到了这个问题,对我来说,类中的一个属性被装饰为[Required],但表在该列中有空值。有道理。一旦我删除了Required,数据就成功地加载了null值。

BookingQuantity-DB中具有空值的列。但实际DB BookingQuantity不是空列。在一些罕见的情况下,它碰巧进入。在这种情况下,下面的代码抛出错误,即相同的错误(数据为Null。不能对Null值调用此方法或属性)。

totalBookingQuantity += item.InspPoTransactions.Where(x => x.PoId == inspectionPODetail.PoId && x.ProductId == inspectionPODetail.ProductId).Sum(x => Convert.ToInt32(x.BookingQuantity));

此错误可能是由于用户对数据库缺乏权限而导致的。检查用户是否至少具有EXECUTE、SELECT或SHOW DATABASES权限