数据是空的.无法在Null值上调用此方法或属性

hol*_*ard 46 c# sql asp.net stored-procedures

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

问题出现在下面的方法中,并抛出以下异常: 数据为空.无法在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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这个:

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
Run Code Online (Sandbox Code Playgroud)

kaj*_*kaj 65

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

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

假设GenreID和MovieGenreID是可以为空的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)
});
Run Code Online (Sandbox Code Playgroud)

  • 您可能需要将代码添加为reader.IsDBNull(movieGenreIDIndex)?(int?)null:reader.GetInt32(movieGenreIDIndex) (8认同)
  • 如何找出哪个属性发生了错误? (4认同)

Ros*_*sim 17

在我的 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; }
}

Run Code Online (Sandbox Code Playgroud)

到:

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
}

Run Code Online (Sandbox Code Playgroud)

  • @Jocie 我指的是新的 C# 8 可空引用类型。https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references,这里的“string”可以是“string”或“string?”我在答案中加粗了该措辞以使其更清晰。 (9认同)
  • `string` 可以为空。 (4认同)
  • @Vitani,这似乎更多是一个糟糕的措辞问题。`String` 还不能为空(即 `Nullable&lt;string&gt;`),它只是一个 `class`,它是一个引用类型,而不是一个 `struct`,它是一个值类型。突然间,我们需要在所有这些引用类型后面明确地加上一个问号。我仍然有点不清楚到底为什么。 (2认同)

Pop*_*ren 14

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

尽管字符串可以为空(在旧版本的.net中),并且实体框架甚至使用字符串类型从现有表创建了我的对象,但我必须将类型更改为字符串?输入以拉回数据为空的数据(在可以为空的列中)。

对于数据库表中可为空的列:

错误的:

public string Decision { get; set; }
Run Code Online (Sandbox Code Playgroud)

正确的:

public string? Decision { get; set; }
Run Code Online (Sandbox Code Playgroud)

我以为我遇到了依赖注入的问题。事实证明它是 Entity Framework Core,并且是一个简单的修复。


Amr*_*rhy 9

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

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

我删除了 IsRequired() 并且它工作正常。

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


Kaf*_*Kaf 7

编辑您的select语句,如下所示,以处理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...
Run Code Online (Sandbox Code Playgroud)