(一)- S3 w$ y, Q6 m/ i
3 E: }% Z6 ?7 ~% [% b* \8 {7 |
有没有人遇到这种情况,用 SqlDataAdapter.Update(ds)更新时出错?9 ?; z4 U- _9 o7 Q) g
8 s. `' | [$ t0 j0 @7 n answer: 一般是这样的,如果用设计器将SqlDataAdapter拖到页面中使用时,不会出现这种情况,因为
+ }. S% w/ x- K2 q3 l; q8 Z" |7 x: S* J
系统会自动生成SqlDataAdapter的属性命令,比如: .UpdateCommane insertCommand " u( y2 Y6 n) [# ?
" R" r" W0 v: e5 n& L- F3 d9 Y
selectCommand等。 但是有些程序员不喜欢用设计器,或者是有些地方没必要拖动
& ?% Z: _4 i; w- b$ d+ Y1 i, x; `( s6 `& U8 D6 r0 A
SqlDataAdapter这么个庞大物来实现,那么SqlDataAdapter就不会自动生成相关的查询或更新
9 u- g+ _, R6 u4 B% U9 M2 f5 @+ K
* h: j$ y# h) S" p! {6 S 语句了. 所以当执行到SqlDataAdapter.Update(ds)语句时,SqlDataAdapter桥接器不知道更
1 O. A2 p" C- l" y* c) `0 S V2 u7 V! M
新哪个表.不报错了. : C- O5 L, i( w& @
/ l- m1 x* J T
(二); z S4 F- @; M Z; D M
- `. b7 ~) w1 A% | 解决方法:. \. \/ o3 R; ]
" T3 [6 ~. ~5 G% o 用SqlCommandBuilder 实现批量更新
" G/ g$ G% t! I l$ i& t' G) \ B2 I9 r8 x. N
1.功能:
) S7 ^0 `& d+ _8 c3 _4 c3 _
: w0 r) t. h# v 可以实现你对DataSet在UI层做任意操作后,直接丢给这个方法,这个方法就可以自动把你的修改更 新到数 据库中,而没必要每次都更新到
) Y, \ H/ y$ S' }( C5 @% ~$ ~: T+ c% n! U. U7 L0 R
数据库8 N' d/ p9 A# d# _8 H1 k
# ?# S8 H& {8 t% |, F 2.使用方法
1 P* r% ]6 e( T1 ?& N public int UpdateByDataSet(DataSet ds,string strTblName,string strConnection); M$ i; R" K7 h1 {& |
{
) I3 v* O- j+ n" \ try* c" ]* j t! \, ^6 u& [
{
. _% w; D1 ^ y( s9 F SqlConnection conn = new SqlConnection(strConnection));* l* [; b8 b: M- M6 U- T
) h4 V* V. ~% {- F9 [ SqlDataAdapter myAdapter = new SqlDataAdapter();% O& X9 f. Y: J6 x8 u
SqlCommand myCommand = new SqlCommand("select * from "+strTblName),(SqlConnection)this.conn); ; q/ A6 S% f0 x# s: g
myAdapter.SelectCommand = myCommand;
7 x3 ]/ i0 _) W) C/ I' m1 Q SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(myAdapter);
+ O; C* l8 Z! L* M" \# j1 S myAdapter.Update(ds,strTblName); 3 f1 f. G7 F/ W6 I) I1 q
& N4 h Z( U4 A k. C# K
return 0;
6 o) t) j5 t+ D3 v/ B# b}
% o+ f d) x4 w, C6 O) |catch(BusinessException errBU)6 D7 Z9 N% q& i4 j. \; k5 G
{ & G+ G8 {! \1 L% r7 G6 Y9 o) ?% _! X
throw errBU;. D" ]( F o7 l+ e
} 2 [8 { }' a! t; @2 G) X
catch(Exception err)7 B2 E& o/ c# p" w/ l' L
{
8 k9 Y% w1 h! q, {! v throw new BusinessException(err);! f4 t h5 L' Q2 N( _4 @$ n
}* e# f( V) ^, i% ?
}
& `" g) g' q6 k; B2 N/ _0 z
$ A# r" U0 ?9 L9 N+ l" o直接调用这个方法就可以啦,说明的一点是select * from "+strTblName是一定要的,8 f7 u, N) O2 N& g5 n3 M7 F5 L6 h' n
作用大家也应该想到了,主要是告诉 SqlDataAdapter更新哪个表
! Y* W6 }# i# ~
I2 k) Y W( Q3.什么时候用?2 w6 @8 b) D2 J' n; C' F9 O
3 O- u5 U/ A8 K: ]8 I8 {/ z a. 有时候需要缓存的时候,比如说在一个商品选择界面,选择好商品,并且进行编辑/删除/更新后,2 z! K! h7 X- C" B' x( r3 m; U. ~
( @# `0 W+ K$ ~% o
最后一并交给数据库,而不是每一步操作都访问数据库,因为客户选择商品可能进行n次编辑/删除$ u9 D) r6 A$ N1 O: d8 p
9 j9 O& l$ c8 t; y l# R9 F
更新操作,如果每次都提交,不但容易引起数据库冲突,引发错误,而且当数据量很大时在用户执行
! v9 A0 x- E) Z; u
% w; N: ?$ x1 J7 p, M 效率上也变得有些慢+ H: h. X* `8 C% X
/ ~' L9 \0 o9 n- a2 Z
b.有的界面是这样的有的界面是这样的,需求要求一定用缓存实现,确认之前的操作不提交到库,点击
; ^ V' g" ^( [/ ~" _
8 F7 X4 U& `% \% u1 J 页面专门提交的按钮时才提交商品选择信息和商品的其它信息. 我经常遇到这样的情况
0 p6 u2 w! F0 t; C- b5 [1 Q& z
, I9 a" ]- b8 M; `: g, @) \1 u c.有些情况下只往数据库里更新,不读取. 也就是说没有从数据库里读,SqlDataAdapter也就不知道是
0 h3 s) O* Q! \( I" X 4 d+ ^$ x$ I7 S1 G: L% X( f5 r
更新哪张表了,调用Update就很可能出错了。这样的情况下可以用SqlCommandBuilder 了.
8 c% x _6 C; c; f& M: j% ]
' J. I7 C+ S8 l1 @
4 h3 n0 E) x# ~! M5 {$ Y5 ~4.
4 ^/ A) m: g d7 b; H注意点: : m. K6 Z: x, L0 k7 m
1.只能更新一个表,不能更新两个或两个以上相关联的表) |8 @4 N7 m% Q: t% Z- ^# a2 a
2.表中必须有主键
2 `! u" O5 F4 C, h; E I 3.更新的表中字段不能有image类型的
! j! N0 n. g% }! Z& N, {- }( \
+ }- z# E4 w: v; m- f& R5.优点:( w5 ^6 s: U8 i& N3 c) l
+ j2 ^ ]% S( o1 Q
节省代码量,节省时间,这个方法可以代替所有的: 更新/删除/插入操作语句
8 n, b4 a1 o+ e$ G/ ]/ a
3 q! ~# X: X! @6 Q. [( c% j6.缺点:
; k, P6 h/ a7 z7 Q' {( | 访问两次数据库(select * TableName,就是这句,要确认是哪个表,除非是很大的数据量,# L0 r8 E/ q6 L% u
一般是感觉不到的),效率有些慢 |