vb.net - Class 'System.DBNull' cannot be indexed because it has no default property -
private sub button1_click(byval sender system.object, byval e system.eventargs) handles button1.click cn.open() dim arrimage() byte dim ms new memorystream() if (pb1.image isnot nothing) pb1.image.save(ms, pb1.image.rawformat) arrimage = ms.getbuffer ms.close() end if cmd .connection = cn .commandtext = "insert [example]([pname],[pic])values(@a2,@a1)" .parameters.add("a0", oledbtype.varchar).value = tname.text .parameters.add("a1", oledbtype.binary).value = iif(pb1.image isnot nothing, arrimage, dbnull.value()) .dispose() .executenonquery() end cn.close() end sub
you have multiple issues in code. in order of appearance:
dont use getbuffer()
as noted on msdn, buffer can twice size of data in stream. bloat database needlessly nulls. use toarray()
instead.
since images in db have converted , byte array, consider archiving images folder , store name in database. can prepend archive folder name load image quickly.
rather rawformat, encode jpeg.
use using
blocks
anything has .dispose
method needs disposed. apply oledbcommand
object (memstream doesnt need disposed, implementaion detail).
using
blocks incoporate dim
, new
, dispose
in 1 handy, easy use block:
using foo new foobar() ... end using
the first line declares foo
variable, , creates instance of foobar
can use inside block. @ end, disposed of automatically.
don't use global dbcommand objects
your code not show cmd
being declared or created, must form level object. don't that. there nothing reusable dbcommand
object unless app 1 thing.
in code add 2 parameters. next time go use it, still have 2 , code add 2 more more sql query requires. in case, code disposes of it, that means next time go reference objectdisposedexception
.
- as noted, code calls
dispose
beforeexecutenonquery
crash - cant use disposed object.
dbnull.value
not method
as compiler error, have this:
iif(pb1.image isnot nothing, arrimage, dbnull.value())
dbnull.value property, not method, parens not needed. also, should use "new" if
operator rather old iif
function. operator short-circuited part/clause not apply ignored:
' should evaluate data (arrimage) not source if(pb1.image isnot nothing, arrimage, dbnull.value) ' no parens
revamped code:
cn.open() dim arrimage() byte = nothing if (pb.image isnot nothing) using ms new memorystream() pb.image.save(ms, imageformat.jpeg) arrimage = ms.toarray() end using end if dim sql = "insert [example]([pname],[pic]) values (@a2,@a1)" using cmd new oledbcommand(sql, cn) cmd.parameters.add("a0", oledbtype.varchar).value = tname.text if arrimage isnot nothing cmd.parameters.add("a1", oledbtype.varbinary).value = arrimage else cmd.parameters.add("a1", oledbtype.varbinary).value = dbnull.value end if cmd.executenonquery() end using cn.close()
- since command object useless without both query , connection, prefer pass them in constructor. makes code shorter assures has needs
- connections ought created, used , disposed of each time
- it easy create handy extension method converting image byte array
Comments
Post a Comment