2012-03-15 61 views
34

Tôi đang làm việc trên một ứng dụng mà người ta có thể lấy thông tin về phim từ cơ sở dữ liệu cũng như thêm, cập nhật và xóa phim. Trong cơ sở dữ liệu tôi có ba bảng (Phim, Thể loại và MovieGenre < - lưu trữ phim và thể loại của chúng). Tất cả mọi thứ hoạt động tốt ngoài một điều, và đó là khi một bộ phim không có bất kỳ thể loại nào (nên có thể).Dữ liệu là Null. Không thể gọi phương thức hoặc thuộc tính này trên các giá trị Null

Sự cố xảy ra theo phương pháp bên dưới và ngoại lệ sau được ném: Dữ liệu là Null. Không thể gọi phương thức hoặc thuộc tính này trên các giá trị Null.

Lý do (tất nhiên) là sproc trả về null vì phim không có bất kỳ thể loại nào, nhưng tôi không thể tìm ra cách ngăn chặn ngoại lệ này. Như tôi đã nói, có thể lưu trữ phim mà không lưu trữ bất kỳ thông tin nào về thể loại/s.

Cảm ơn trước!

Phương pháp:

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(); 
     } 
    } 
} 

Các 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 
+9

này: 'catch {ném Appl mới icationException(); } 'là một ý tưởng khá tồi. Bạn đang mất TẤT CẢ thông tin ngữ cảnh. Ít nhất là vượt qua ngoại lệ bị bắt về như là ngoại lệ bên trong: 'catch (Exception ex) {throw new ApplicationException (cũ); } ' –

Trả lời

47

Bạn không cần phải cố gắng để chuyển đổi các giá trị null từ các proc vào ints - vì vậy trước khi bạn tạo ra các ví dụ MovieGenre bạn cần phải kiểm tra các lĩnh vực nullable bằng cách sử dụng phương pháp SqlDataReader.IsDBNull:

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

Giả sử rằng các GenreID và MovieGenreID được ints nullable bạn có thể làm một cái gì đó như:

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

bạn có thể cần phải thêm mã như reader.IsDBNull (movieGenreIDIndex)? (int?) null: reader.GetInt32 (movieGenreIDIndex) – akd

5

Sửa chọn tuyên bố của bạn như sau để giải quyết vấn đề 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... 
+0

Cảm ơn bạn đã trả lời. Tôi đã thử mã của bạn nhưng tiếc là tôi nhận được cùng một lỗi:/ – holyredbeard

+0

Tôi đã sử dụng ISNULL chỉ cho các cột GenreID và Thể loại để hiển thị cho bạn. Bạn có thể sử dụng nó cho mỗi cột như ** TRẢ LỜI CÂU CHUYỆN ĐỂ BAO GỒM TẤT CẢ CÁC COLUMNS ** – Kaf

2

Câu trả lời đơn giản nhất là thay thế giá trị rỗng bằng giá trị không null. Hãy thử:

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 
+0

1+ cho 'coalesce'' ISNULL' không làm việc cho tôi tôi sử dụng MySql – ygaradon

Các vấn đề liên quan