|
我正在开发一种应用程序,可以从数据库中获取电影信息以及添加,更新和删除电影。在数据库中,我有三个表(电影,流派和电影流派
* g: R* m( F& [6 u0 c在下面的方法中,会发生问题,并引发以下异常: 数据为Null。 不能在Null值上调用此方法或属性。
- j+ q' w/ i- j, s# i, a$ c9 t& D原因(当然)是因为电影没有任何体裁,所以sproc返回null,但是我只是不知道如何防止抛出此异常。就像我说的那样,应该可以在不存储任何流派信息的情况下存储电影。
/ T; K. L+ t5 A4 x, `! V$ Q提前致谢!
: i, Y2 g3 q7 B9 R方法:% _6 ]' E$ L2 t! X2 v, C" N
public List GetMovieGenrebyMovieID(int movieID) {
/ U- k; Q; b5 l. g2 Z N* ]% ] using (SqlConnection conn = CreateConnection()) {9 I' x- V& m9 `, v# C
try {
$ z8 F, m# s! G# T9 _* Q5 g! G SqlCommand cmd = new SqlCommand("dbo.usp_GetMovieGenreByMovieID", conn);
0 `1 Y( \* @8 p# @ cmd.CommandType = CommandType.StoredProcedure;' b( Y9 @* N/ m
cmd.Parameters.AddWithValue("@MovieID", movieID);/ }2 Q% G9 F6 {: w- F6 i
List movieGenre = new List(10);
/ i" S" M& q: _) a3 u conn.Open();1 U+ L6 Q$ [0 f) F$ V/ \1 d; _% J
using (SqlDataReader reader = cmd.ExecuteReader()) {* @) g+ S! y0 L* t) D
int movieGenreIDIndex = reader.GetOrdinal("MovieGenreID");
' i( k) K" p- x8 m0 Z int movieIDIndex = reader.GetOrdinal("MovieID");
+ Z2 C. x2 w5 k! q% u( R int genreIDIndex = reader.GetOrdinal("GenreID");6 ]1 U0 U' c5 f- B0 P! r5 A
while (reader.Read()) {
; ]; w6 }$ a) J- l( ^/ W" o) O movieGenre.Add(new MovieGenre {
2 T/ t4 \9 Y5 H q/ o1 v1 ~* K1 c MovieID = reader.GetInt32(movieIDIndex),1 X. O7 L' Y9 a( }. W* N" J6 l
MovieGenreID = reader.GetInt32(movieGenreIDIndex),; R! T3 b+ E+ Z
GenreID = reader.GetInt32(genreIDIndex)0 ?6 D* {5 u6 L# x0 R! N
});
( n$ H! G8 K. v( x# u" } }
# l/ Q+ Y& O; U1 I6 F4 S }
* w; K2 W; m' b% x movieGenre.TrimExcess();
! |) P# C% d, ~% R7 `( Y. W return movieGenre;
! M5 d& M6 T+ u- R5 G' ? }8 I8 H) _$ ^3 T# q6 H8 t
catch {+ A* @7 L% a7 E: h# l2 [& u0 Q
throw new ApplicationException();- E! h0 C3 ]& S/ O8 Y
}
, m w% m# j1 z' K2 G+ B+ X }$ u: i! I V" E
}# x N5 w& l) Q* L
程序:6 ^6 h/ y: w3 V
ALTER PROCEDURE usp_GetMovieGenreByMovieID# t* S: x! I* f0 e0 m& m- c F4 y
@MovieID int
$ W% h0 D* O$ L0 |4 N9 XAS' O6 C* {9 {: F {- ?3 ~4 d
BEGIN: K5 h8 ?$ {5 k/ \
BEGIN TRY3 O. P, W% @7 C/ Y$ n$ b% u
SELECT m.MovieID, g.GenreID, mg.MovieGenreID, g.Genre
& \/ s w2 v% k9 |: O8 L" ] FROM Movie AS m9 f' Y) o# n3 _6 w w5 g
LEFT JOIN MovieGenre AS mg% i% t$ C0 M+ ?3 q( r; C
ON m.MovieId = mg.MovieID D1 [( {+ e% [
LEFT JOIN Genre AS g
# a' o% Y9 V: q/ R# E ON mg.GenreID = g.GenreID
, ~, @' q$ ]+ Z$ A1 M& x& A0 b7 o WHERE m.MovieID = @MovieID
' s: W) X& v1 m. i0 m# l END TRY O2 `( v+ }+ v
BEGIN CATCH7 ~+ b1 c* o' q8 Q
RAISERROR ('Error while trying to receive genre(s).',16,1)
" U. y+ R1 }4 s% {1 U END CATCH# V' d/ Q) T9 R) |, A) B. ?' Q7 h
END! x2 _# v3 T6 ^2 e' w- J
! U9 c# U1 R7 d6 K
解决方案:( K; I9 ]7 B n
2 R5 {3 p' V' ~- n
6 u% _9 k& h! ^/ P8 m0 v- h
) ]+ M# ^4 D' s3 Z9 X/ B2 e1 Q3 M8 ]
您不应该尝试将proc的null值转换为ints-- @0 N3 {! e7 M a
因此,在创建MovieGenre实例之前,需要使用以下SqlDataReader.IsDBNull方法检查可为空的字段:
. r: m7 E) Z2 v; `% Qhttp://msdn.microsoft.com/zh-
- o# Z0 l+ j0 O. B- Y" l5 U8 A! R5 i% s; ACN/library/system.data.sqlclient.sqldatareader.isdbnull.aspx
9 C. N( b( J5 D; O% T& W0 l" M d5 c假设GenreID和MovieGenreID是可为null的整数,则可以执行以下操作:
) K4 V) ]8 _" ]0 D8 `movieGenre.Add(new MovieGenre {
0 h1 t% F- I( p( d MovieID = reader.GetInt32(movieIDIndex),, x0 v- g' T; K8 Y2 @0 w
MovieGenreID = reader.IsDBNull(movieGenreIDIndex) ? null : reader.GetInt32(movieGenreIDIndex),
. Y0 J+ @4 @9 M9 D4 l" G, Y GenreID = reader.IsDBNull(genreIDIndex) ? null : reader.GetInt32(genreIDIndex)) V% }1 C% i1 I
}); |
|