web-dev-qa-db-ja.com

データはヌルです。このメソッドまたはプロパティは、Null値で呼び出すことはできません

私は、データベースから映画に関する情報を取得したり、映画を追加、更新、削除できるアプリケーションを開発しています。データベースには3つのテーブルがあります(Movie、Genre、MovieGenre <-映画とそのジャンルを保存します)。 1つだけでなく、すべてが正常に機能します。そのとき、映画にはジャンルがありません(可能なはずです)。

以下のメソッドで問題が発生し、次の例外がスローされます。データは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();
        }
    }
}

sproc:

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
44
holyredbeard

Procのnull値をintに変換しようとするべきではありません。したがって、MovieGenreインスタンスを作成する前に、SqlDataReader.IsDBNullメソッドを使用してnull値を許可するフィールドを確認する必要があります。

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

CategoriesIDとMovieGenreIDがnull入力可能な整数であると仮定すると、次のようなことができます。

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

Nullの問題を処理するには、selectステートメントを次のように編集します。

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

最も簡単な答えは、ヌルをヌル以外の値に置き換えることです。試してください:

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
2
user359040