繁体   English   中英

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

[英]Data is Null. This method or property cannot be called on Null values

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

问题出现在下面的方法中,并抛出以下异常: Data is Null。 不能对 Null 值调用此方法或属性。

原因(当然)是 sproc 返回 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

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

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

假设 GenreID 和 MovieGenreID 是可为空的整数,您可以执行以下操作:

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

在我的 Entity Framework Core 3.1 项目中启用 C# 8 可空功能后,立即发生此错误。

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

更改自:

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
}

按如下方式编辑您的选择语句以处理空问题。

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...

在我的情况下,我使用的是 EF Core,问题是该字段在数据库中可以为空,但在 ModelCreating 中它是必需的:

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

我删除了 IsRequired() 并且效果很好。

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

如果有人遇到过这个问题,这就是我的情况。

我正在构建 WEB Api。 在我放置 [Required] Attribue - https://docs.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 值。

我希望它对某人有所帮助。

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

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

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

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

即使字符串可以为空,并且 Entity Framework 甚至使用字符串类型从现有表中创建了我的对象,我也必须将字符串列的类型更改为字符串? 键入以拉回数据为空的数据。

错误的:

public string Decision { get; set; }

正确的:

public string? Decision { get; set; }

我以为我遇到了依赖注入问题。 原来它是 Entity Framework Core,它是一个简单的修复。

今天我遇到了这个问题。 但是我的已经以另一种方式修复了。 如果有一天有人偶然发现答案是给他们的。

因为这是一个通用的 C# .NET CLI 异常

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

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

就这样。

谢谢你。

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

BookingQuantity - 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 权限

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM