1. ホーム
  2. c#

[解決済み] データがNullです。このメソッドまたはプロパティは、Null 値に対して呼び出すことはできません。

2023-07-04 01:54:05

質問

データベースから映画に関する情報を取得し、映画の追加、更新、削除を行うアプリケーションに取り組んでいます。データベースには、3 つのテーブル (映画、ジャンル、MovieGenre <- 映画とそのジャンルを格納) があります。それは、映画がどのジャンルも持っていないときです(これは可能なはずです)。

問題は以下のメソッドで発生し、以下の例外がスローされます。 データはNullです。このメソッドまたはプロパティは、Null値に対して呼び出すことはできません。

理由は (もちろん) ムービーにジャンルがないため、sproc が null を返すからですが、この例外がスローされるのを防ぐ方法がどうしてもわかりません。私が言ったように、ジャンル/s の情報を保存せずに映画を保存することは可能であるべきです。

前もってありがとうございます!

メソッドです。

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 値を int 型に変換してはいけません。したがって、MovieGenre インスタンスを作成する前に、null 可能なフィールドを SqlDataReader.IsDBNull メソッドを使用して null 可能なフィールドをチェックする必要があります。

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

GenreIDとMovieGenreIDがnullable 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)
});