0% found this document useful (0 votes)
60 views20 pages

Data Tutorial 66 VB

This tutorial demonstrates how to create a batch inserting interface in ASP.NET that allows users to add multiple records to a database with one submission. The tutorial creates a page with two panels - one to display existing records in a GridView, and another to contain the inserting interface which includes dropdowns to select a category and supplier, and textboxes for multiple product names and prices. When the "Process Product Shipment" button is clicked, the panels swap visibility so the inserting interface is shown to allow adding new products in a batch all associated with the selected category and supplier.

Uploaded by

arechor1605
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views20 pages

Data Tutorial 66 VB

This tutorial demonstrates how to create a batch inserting interface in ASP.NET that allows users to add multiple records to a database with one submission. The tutorial creates a page with two panels - one to display existing records in a GridView, and another to contain the inserting interface which includes dropdowns to select a category and supplier, and textboxes for multiple product names and prices. When the "Process Product Shipment" button is clicked, the panels swap visibility so the inserting interface is shown to allow adding new products in a batch all associated with the selected category and supplier.

Uploaded by

arechor1605
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Thistutorialispartofaset.FindoutmoreaboutdataaccesswithASP.

NETintheWorkingwithData
inASP.NET2.0sectionoftheASP.NETsiteathttp://www.asp.net/learn/dataaccess/default.aspx.

WorkingwithDatainASP.NET2.0::BatchInserting
Introduction
Inthe BatchUpdatingtutorialwelookedatcustomizingtheGridViewcontroltopresentaninterfacewhere
multiplerecordswereeditable.Theuservisitingthepagecouldmakeaseriesofchangesandthen,withasingle
buttonclick,performabatchupdate.Forsituationswhereuserscommonlyupdatemanyrecordsinonego,suchan
interfacecansavecountlessclicksandkeyboardtomousecontextswitcheswhencomparedtothedefaultperrow
editingfeaturesthatwerefirstexploredbackinthe AnOverviewofInserting,Updating,andDeletingData
tutorial.
Thisconceptcanalsobeappliedwhenaddingrecords.ImaginethathereatNorthwindTraderswecommonly
receiveshipmentsfromsuppliersthatcontainanumberofproductsforaparticularcategory.Asanexample,we
mightreceiveashipmentofsixdifferentteaandcoffeeproductsfromTokyoTraders.Ifauserentersthesix
productsoneatatimethroughaDetailsViewcontrol,theywillhavetochoosemanyofthesamevaluesoverand
overagain:theywillneedtochoosethesamecategory(Beverages),thesamesupplier(TokyoTraders),thesame
discontinuedvalue(False),andthesameunitsonordervalue(0).Thisrepetitivedataentryisnotonlytime
consuming,butispronetoerrors.
Withalittleworkwecancreateabatchinsertinginterfacethatenablestheusertochoosethesupplierandcategory
once,enteraseriesofproductnamesandunitprices,andthenclickabuttontoaddthenewproductstothe
database(seeFigure1).Aseachproductisadded,its ProductName andUnitPrice datafieldsareassignedthe
valuesenteredintheTextBoxes,whileitsCategoryID andSupplierID valuesareassignedthevaluesfromthe
DropDownListsatthetopfotheform.TheDiscontinued andUnitsOnOrder valuesaresettothehardcoded
valuesofFalse and0,respectively.

Figure1:TheBatchInsertingInterface

1 of20

InthistutorialwewillcreateapagethatimplementsthebatchinsertinginterfaceshowninFigure1.Aswiththe
previoustwotutorials,wewillwraptheinsertionswithinthescopeofatransactiontoensureatomicity.Letsget
started!

Step1:CreatingtheDisplayInterface
Thistutorialwillconsistofasinglepagethatisdividedintotworegions:adisplayregionandaninsertingregion.
Thedisplayinterface,whichwellcreateinthisstep,showstheproductsinaGridViewandincludesabuttontitled
ProcessProductShipment. Whenthisbuttonisclicked,thedisplayinterfaceisreplacedwiththeinserting
interface,whichisshowninFigure1.Thedisplayinterfacereturnsafterthe AddProductsfromShipmentor
Cancel buttonsareclicked.WellcreatetheinsertinginterfaceinStep2.
Whencreatingapagethathastwointerfaces,onlyoneofwhichisvisibleatatime,eachinterfacetypicallyis
placedwithinaPanelWebcontrol,whichservesasacontainerforothercontrols.Therefore,ourpagewillhave
twoPanelcontrolsoneforeachinterface.
StartbyopeningtheBatchInsert.aspx pageintheBatchData folderanddragaPanelfromtheToolboxontothe
Designer(seeFigure2).SetthePanelsID propertytoDisplayInterface.WhenaddingthePaneltothe
Designer,itsHeight andWidth propertiesaresetto50pxand125px,respectively.Clearoutthesepropertyvalues
fromthePropertieswindow.

Figure2:DragaPanelfromtheToolboxontotheDesigner

Next,dragaButtonandGridViewcontrolintothePanel.SettheButtonsID propertytoProcessShipment andits


Text propertytoProcessProductShipment. SettheGridViewsID propertytoProductsGrid and,fromits
smarttag,bindittoanewObjectDataSourcenamedProductsDataSource. ConfiguretheObjectDataSourceto
pullitsdatafromtheProductsBLL classsGetProducts method.SincethisGridViewisusedonlytodisplaydata,
setthedropdownlistsintheUPDATE,INSERT,andDELETEtabsto (None). ClickFinishtocompletethe
2 of20

ConfigureDataSourcewizard.

Figure3:DisplaytheDataReturnedfromtheProductsBLL ClasssGetProducts Method

3 of20

Figure4:SettheDropDownListsintheUPDATE,INSERT,andDELETETabsto(None)

AftercompletingtheObjectDataSourcewizard,VisualStudiowilladdBoundFieldsandaCheckBoxFieldforthe
productdatafields.RemoveallbuttheProductName,CategoryName,SupplierName,UnitPrice,and
Discontinued fields.Feelfreetomakeanyaestheticcustomizations.IdecidedtoformattheUnitPrice fieldasa
currencyvalue,reorderedthefields,andrenamedseveralofthefieldsHeaderText values.Alsoconfigurethe
GridViewtoincludepagingandsortingsupportbycheckingtheEnablePagingandEnableSorting
checkboxesintheGridViewssmarttag.
AfteraddingthePanel,Button,GridView,andObjectDataSourcecontrolsandcustomizingtheGridViewsfields,
yourpagesdeclarativemarkupshouldlooksimilartothefollowing:
<asp:PanelID="DisplayInterface"runat="server">
<p>
<asp:ButtonID="ProcessShipment"runat="server"
Text="ProcessProductShipment"/>
</p>
<asp:GridViewID="ProductsGrid"runat="server"AllowPaging="True"
AllowSorting="True"AutoGenerateColumns="False"
DataKeyNames="ProductID"DataSourceID="ProductsDataSource">
<Columns>
<asp:BoundFieldDataField="ProductName"HeaderText="Product"
SortExpression="ProductName"/>
<asp:BoundFieldDataField="CategoryName"HeaderText="Category"
ReadOnly="True"SortExpression="CategoryName"/>
<asp:BoundFieldDataField="SupplierName"HeaderText="Supplier"
ReadOnly="True"SortExpression="SupplierName"/>

4 of20

<asp:BoundFieldDataField="UnitPrice"DataFormatString="{0:c}"
HeaderText="Price"HtmlEncode="False"
SortExpression="UnitPrice">
<ItemStyleHorizontalAlign="Right"/>
</asp:BoundField>
<asp:CheckBoxFieldDataField="Discontinued"HeaderText="Discontinued"
SortExpression="Discontinued">
<ItemStyleHorizontalAlign="Center"/>
</asp:CheckBoxField>
</Columns>
</asp:GridView>
<asp:ObjectDataSourceID="ProductsDataSource"runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts"TypeName="ProductsBLL">
</asp:ObjectDataSource>
</asp:Panel>

NotethatthemarkupfortheButtonandGridViewappearwithintheopeningandclosing<asp:Panel> tags.Since
thesecontrolsarewithintheDisplayInterface Panel,wecanhidethembysimplysettingthePanelsVisible
propertytoFalse.Step3looksatprogrammaticallychangingthePanelsVisible propertyinresponsetoabutton
clicktoshowoneinterfacewhilehidingtheother.
Takeamomenttoviewourprogressthroughabrowser.AsFigure5shows,youshouldseeaProcessProduct
ShipmentbuttonaboveaGridViewthatliststheproductstenatatime.

Figure5:TheGridViewListstheProductsandOffersSortingandPagingCapabilities

5 of20

Step2:CreatingtheInsertingInterface
Withthedisplayinterfacecomplete,werereadytocreatetheinsertinginterface.Forthistutorial,letscreatean
insertinginterfacethatpromptsforasinglesupplierandcategoryvalueandthenallowstheusertoenteruptofive
productnamesandunitpricevalues.Withthisinterface,theusercanaddonetofivenewproductsthatallsharethe
samecategoryandsupplier,buthaveuniqueproductnamesandprices.
StartbydraggingaPanelfromtheToolboxontotheDesigner,placingitbeneaththeexistingDisplayInterface
Panel.SettheID propertyofthisnewlyaddedPaneltoInsertingInterface andsetitsVisible propertyto
False.WelladdcodethatsetstheInsertingInterface PanelsVisible propertytoTrue inStep3.Alsoclear
outthePanelsHeight andWidth propertyvalues.
Next,weneedtocreatetheinsertinginterfacethatwasshownbackinFigure1.Thisinterfacecanbecreated
throughavarietyofHTMLtechniques,butwewilluseafairlystraightforwardone:afourcolumn,sevenrow
table.
Note:WhenenteringmarkupforHTML<table> elements,IprefertousetheSourceview.WhileVisual
Studiodoeshavetoolsforadding <table> elementsthroughtheDesigner,theDesignerseemsalltoowilling
toinjectunaskedforstyle settingsintothemarkup.OnceIhavecreatedthe<table> markup,Iusually
returntotheDesignertoaddtheWebcontrolsandsettheirproperties.Whencreatingtableswithpre
determinedcolumnsandrowsIpreferusingstaticHTMLratherthantheTableWebcontrol becauseany
WebcontrolsplacedwithinaTableWebcontrolcanonlybeaccessedusingtheFindControl
("controlID") pattern.Ido,however,useTableWebcontrolsfordynamicallysizedtables(oneswhose
rowsorcolumnsarebasedonsomedatabaseoruserspecifiedcriteria),sincetheTableWebcontrolcanbe
constructedprogrammatically.
Enterthefollowingmarkupwithinthe<asp:Panel> tagsoftheInsertingInterface Panel:
<tableclass="DataWebControlStyle"cellspacing="0">
<trclass="BatchInsertHeaderRow">
<tdclass="BatchInsertLabel">Supplier:</td>
<td></td>
<tdclass="BatchInsertLabel">Category:</td>
<td></td>
</tr>
<trclass="BatchInsertRow">
<tdclass="BatchInsertLabel">Product:</td>
<td></td>
<tdclass="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<trclass="BatchInsertAlternatingRow">
<tdclass="BatchInsertLabel">Product:</td>
<td></td>
<tdclass="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<trclass="BatchInsertRow">
<tdclass="BatchInsertLabel">Product:</td>
<td></td>
<tdclass="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<trclass="BatchInsertAlternatingRow">

6 of20

<tdclass="BatchInsertLabel">Product:</td>
<td></td>
<tdclass="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<trclass="BatchInsertRow">
<tdclass="BatchInsertLabel">Product:</td>
<td></td>
<tdclass="BatchInsertLabel">Price:</td>
<td></td>
</tr>
<trclass="BatchInsertFooterRow">
<tdcolspan="4">
</td>
</tr>
</table>

This<table> markupdoesnotincludeanyWebcontrolsyet,welladdthosemomentarily.Notethateach<tr>
elementcontainsaparticularCSSclasssetting:BatchInsertHeaderRow fortheheaderrowwherethesupplier
andcategoryDropDownListswillgoBatchInsertFooterRow forthefooterrowwheretheAddProductsfrom
ShipmentandCancelButtonswillgoandalternatingBatchInsertRow andBatchInsertAlternatingRow
valuesfortherowsthatwillcontaintheproductandunitpriceTextBoxcontrols.IvecreatedcorrespondingCSS
classesintheStyles.css filetogivetheinsertinginterfaceanappearancesimilartotheGridViewand
DetailsViewcontrolsweveusedthroughoutthesetutorials.TheseCSSclassesareshownbelow.
/***Stylesfor~/BatchData/BatchInsert.aspxtutorial***/
.BatchInsertLabel
{
fontweight:bold
textalign:right
}
.BatchInsertHeaderRowtd
{
color:White
backgroundcolor:#900
padding:11px
}
.BatchInsertFooterRowtd
{
textalign:center
paddingtop:5px
}
.BatchInsertRow
{
}
.BatchInsertAlternatingRow
{
backgroundcolor:#fcc
}

Withthismarkupentered,returntotheDesignview.This<table> shouldshowasafourcolumn,sevenrowtable
intheDesigner,asFigure6illustrates.
7 of20

Figure6:TheInsertingInterfaceisComposedofaFourColumn,SevenRowTable

WerenowreadytoaddtheWebcontrolstotheinsertinginterface.DragtwoDropDownListsfromtheToolbox
intotheappropriatecellsinthetable oneforthesupplierandoneforthecategory.
SetthesupplierDropDownListsID propertytoSuppliers andbindittoanewObjectDataSourcenamed
SuppliersDataSource.ConfigurethenewObjectDataSourcetoretrieveitsdatafromtheSuppliersBLL classs
GetSuppliers methodandsettheUPDATEtabsdropdownlistto(None). ClickFinishtocompletethe
wizard.

8 of20

Figure7:ConfiguretheObjectDataSourcetoUsetheSuppliersBLL ClasssGetSuppliers Method

HavetheSuppliers DropDownListdisplaytheCompanyName datafieldandusetheSupplierID datafieldasits


ListItems values.

9 of20

Figure8:DisplaytheCompanyName DataFieldandUseSupplierID astheValue

NamethesecondDropDownListCategories andbindittoanewObjectDataSourcenamed
CategoriesDataSource.ConfiguretheCategoriesDataSource ObjectDataSourcetousetheCategoriesBLL
classsGetCategories methodsetthedropdownlistsintheUPDATEandDELETEtabsto(None)andclick
Finishtocompletethewizard.Finally,havetheDropDownListdisplaytheCategoryName datafieldandusethe
CategoryID asthevalue.
AfterthesetwoDropDownListshavebeenaddedandboundtoappropriatelyconfiguredObjectDataSources,your
screenshouldlooksimilartoFigure9.

10 of20

Figure9:TheHeader RowNowContainstheSuppliers andCategories DropDownLists

WenowneedtocreatetheTextBoxestocollectthenameandpriceforeachnewproduct.DragaTextBoxcontrol
fromtheToolboxontotheDesignerforeachofthefiveproductnameandpricerows.SettheID propertiesofthe
TextBoxestoProductName1,UnitPrice1,ProductName2,UnitPrice2,ProductName3,UnitPrice3,andsoon.
AddaCompareValidatoraftereachoftheunitpriceTextBoxes,settingtheControlToValidate propertytothe
appropriateID.AlsosettheOperator propertytoGreaterThanEqual,ValueToCompare to0, andType to
Currency.ThesesettingsinstructtheCompareValidatortoensurethattheprice,ifentered,isavalidcurrency
valuethatisgreaterthanorequaltozero.SettheText propertyto*, andErrorMessage toThepricemustbe
greaterthanorequaltozero.Also,pleaseomitanycurrencysymbols.
Note:TheinsertinginterfacedoesnotincludeanyRequiredFieldValidatorcontrols,eventhoughthe
ProductName fieldinthe Products databasetabledoesnotallowNULL values.Thisisbecausewewantto
lettheuserenteruptofiveproducts.Forexample,iftheuserweretoprovidetheproductnameandunit
priceforthefirstthreerows,leavingthelasttworowsblank,wedjustaddthreenewproductstothesystem.
SinceProductName isrequired,however,wewillneedtoprogrammaticallychecktoensurethatifaunit
priceisenteredthatacorrespondingproductnamevalueisprovided.WelltacklethischeckinStep4.
Whenvalidatingtheusersinput,theCompareValidatorreportsinvaliddataifthevaluecontainsacurrency
symbol.Adda$infrontofeachoftheunitpriceTextBoxestoserveasavisualcuethatinstructstheuserto
omitthecurrencysymbolwhenenteringtheprice.
Lastly,addaValidationSummarycontrolwithintheInsertingInterface Panel,settingsitsShowMessageBox
propertytoTrue anditsShowSummary propertytoFalse.Withthesesettings,iftheuserentersaninvalidunitprice
value,anasteriskwillappearnexttotheoffendingTextBoxcontrolsandtheValidationSummarywilldisplaya
clientsidemessageboxthatshowstheerrormessagewespecifiedearlier.
Atthispoint,yourscreenshouldlooksimilartoFigure10.
11 of20

Figure10:TheInsertingInterfaceNowIncludesTextBoxesfortheProducts NamesandPrices

NextweneedtoaddtheAddProductsfromShipment andCancelbuttonstothefooterrow.Dragtwo
ButtoncontrolsfromtheToolboxintothefooteroftheinsertinginterface,settingtheButtonsID propertiesto
AddProducts andCancelButton andText propertiestoAddProductsfromShipment andCancel,
respectively.Inaddition,settheCancelButton controlsCausesValidation propertytofalse.
Finally,weneedtoaddaLabelWebcontrolthatwilldisplaystatusmessagesforthetwointerfaces.Forexample,
whenausersuccessfullyaddsanewshipmentofproducts,wewanttoreturntothedisplayinterfaceanddisplaya
confirmationmessage.If,however,theuserprovidesapriceforanewproductbutleavesofftheproductname,we
needtodisplayawarningmessagesincetheProductName fieldisrequired.Sinceweneedthismessagetodisplay
forbothinterfaces,placeitatthetopofthepageoutsideofthePanels.
DragaLabelWebcontrolfromtheToolboxtothetopofthepageintheDesigner.SettheID propertyto
StatusLabel,clearouttheText property,andsetthe Visible andEnableViewState propertiesto False.Aswe
haveseeninprevioustutorials,settingtheEnableViewState propertytoFalse allowsustoprogrammatically
changetheLabelspropertyvaluesandhavethemautomaticallyrevertbacktotheirdefaultsonthesubsequent
postback.Thissimplifiesthecodeforshowingastatusmessageinresponsetosomeuseractionthatdisappearson
thesubsequentpostback.Finally,settheStatusLabel controlsCssClass propertytoWarning, whichisthe
nameofaCSSclassdefinedinStyles.css thatdisplaystextinalarge,italic,bold,redfont.
Figure11showstheVisualStudioDesigneraftertheLabelhasbeenaddedandconfigured.

12 of20

Figure11:PlacetheStatusLabel ControlAbovetheTwoPanelControls

Step3:SwitchingBetweentheDisplayandInsertingInterfaces
Atthispointwehavecompletedthemarkupforourdisplayandinsertinginterfaces,butwerestillleftwithtwo
tasks:
l
l

Switchingbetweenthedisplayandinsertinginterfaces
Addingtheproductsintheshipmenttothedatabase

Currently,thedisplayinterfaceisvisiblebuttheinsertinginterfaceishidden.Thisisbecausethe
DisplayInterface PanelsVisible propertyissettoTrue (thedefaultvalue),whiletheInsertingInterface
PanelsVisible propertyissettoFalse.Toswitchbetweenthetwointerfaceswesimplyneedtotoggleeach
controlsVisible propertyvalue.
WewanttomovefromthedisplayinterfacetotheinsertinginterfacewhentheProcessProductShipment button
isclicked.Therefore,createaneventhandlerforthisButtonsClick eventthatcontainsthefollowingcode:
ProtectedSubProcessShipment_Click(senderAsObject,eAsEventArgs)_
HandlesProcessShipment.Click
DisplayInterface.Visible=False
InsertingInterface.Visible=True
EndSub

ThiscodesimplyhidestheDisplayInterface PanelandshowstheInsertingInterface Panel.


Next,createeventhandlersfortheAddProductsfromShipment andCancelButtoncontrolsintheinserting
interface.WheneitheroftheseButtonsisclicked,weneedtorevertbacktothedisplayinterface.CreateClick
eventhandlersforbothButtoncontrolssothattheycallReturnToDisplayInterface,amethodwewilladd
momentarily.InadditiontohidingtheInsertingInterface PanelandshowingtheDisplayInterface Panel,the
13 of20

ReturnToDisplayInterface methodneedstoreturntheWebcontrolstotheirpreeditingstate.Thisinvolves
settingtheDropDownListsSelectedIndex propertiesto0andclearingouttheText propertiesoftheTextBox

controls.
Note:Considerwhatmighthappenifwedidntreturnthecontrolstotheirpreeditingstatebeforereturning
tothedisplayinterface.AusermightclicktheProcessProductShipmentbutton,entertheproductsfrom
theshipment,andthenclickAddProductsfromShipment. Thiswouldaddtheproductsandreturntheuser
tothedisplayinterface.Atthispointtheusermightwanttoaddanothershipment.Uponclickingthe
ProcessProductShipmentbuttontheywouldreturntotheinsertinginterfacebuttheDropDownList
selectionsandTextBoxvalueswouldstillbepopulatedwiththeirpreviousvalues.
ProtectedSubAddProducts_Click(senderAsObject,eAsEventArgs)_
HandlesAddProducts.Click
'TODO:Savetheproducts
'Reverttothedisplayinterface
ReturnToDisplayInterface()
EndSub
ProtectedSubCancelButton_Click(senderAsObject,eAsEventArgs)_
HandlesCancelButton.Click
'Reverttothedisplayinterface
ReturnToDisplayInterface()
EndSub
ConstfirstControlIDAsInteger=1
ConstlastControlIDAsInteger=5
PrivateSubReturnToDisplayInterface()
'Resetthecontrolvaluesintheinsertinginterface
Suppliers.SelectedIndex=0
Categories.SelectedIndex=0
ForiAsInteger=firstControlIDTolastControlID
CType(InsertingInterface.FindControl_
("ProductName"+i.ToString()),TextBox).Text=String.Empty
CType(InsertingInterface.FindControl_
("UnitPrice"+i.ToString()),TextBox).Text=String.Empty
Next
DisplayInterface.Visible=True
InsertingInterface.Visible=False
EndSub

BothClick eventhandlerssimplycalltheReturnToDisplayInterface method,althoughwellreturntotheAdd


ProductsfromShipmentClick eventhandlerinStep4andaddcodetosavetheproducts.
ReturnToDisplayInterface startsbyreturningtheSuppliers andCategories DropDownListstotheirfirst
options.ThetwoconstantsfirstControlID andlastControlID markthestartingandendingcontrolindex
valuesusedinnamingtheproductnameandunitpriceTextBoxesintheinsertinginterfaceandareusedinthe
boundsoftheFor loopthatsetstheText propertiesoftheTextBoxcontrolsbacktoanemptystring.Finally,the
PanelsVisible propertiesareresetsothattheinsertinginterfaceishiddenandthedisplayinterfaceshown.
Takeamomenttotestoutthispageinabrowser.Whenfirstvisitingthepageyoushouldseethedisplayinterface
aswasshowninFigure5.ClicktheProcessProductShipmentbutton.Thepagewillpostbackandyoushould
nowseetheinsertinginterfaceasshowninFigure12.ClickingeithertheAddProductsfromShipment or

14 of20

Cancel buttonsreturnsyoutothedisplayinterface.
Note:Whileviewingtheinsertinginterface,takeamomenttotestouttheCompareValidatorsontheunit
priceTextBoxes.YoushouldseeaclientsidemessageboxwarningwhenclickingtheAddProductsfrom
Shipmentbuttonwithinvalidcurrencyvaluesorpriceswithavaluelessthanzero.

Figure12:TheInsertingInterfaceisDisplayedAfterClickingtheProcessProductShipmentButton

Step4:AddingtheProducts
AllthatremainsforthistutorialistosavetheproductstothedatabaseintheAddProductsfromShipment
ButtonsClick eventhandler.ThiscanbeaccomplishedbycreatingaProductsDataTable andaddinga
ProductsRow instanceforeachoftheproductnamessupplied.OncetheseProductsRowshavebeenaddedwewill
makeacalltotheProductsBLL classsUpdateWithTransaction methodpassingintheProductsDataTable.
RecallthattheUpdateWithTransaction method,whichwascreatedbackintheWrappingDatabase
ModificationswithinaTransaction tutorial,passestheProductsDataTable totheProductsTableAdapters
UpdateWithTransaction method.Fromthere,anADO.NETtransactionisstartedandtheTableAdatperissuesan
INSERT statementtothedatabaseforeachaddedProductsRow intheDataTable.Assumingallproductsareadded
withouterror,thetransactioniscommitted,otherwiseitisrolledback.
ThecodefortheAddProductsfromShipmentButtonsClick eventhandleralsoneedstoperformabitoferror
checking.SincetherearenoRequiredFieldValidatorsusedintheinsertinginterface,ausercouldenterapricefora
productwhileomittingitsname.Sincetheproductsnameisrequired,ifsuchaconditionunfoldsweneedtoalert
theuserandnotproceedwiththeinserts.ThecompleteClick eventhandlercodefollows:
ProtectedSubAddProducts_Click(senderAsObject,eAsEventArgs)_
HandlesAddProducts.Click
'MakesurethattheUnitPriceCompareValidatorsreportvaliddata...
IfNotPage.IsValidThenExitSub
'AddnewProductsRowstoaProductsDataTable...
DimproductsAsNewNorthwind.ProductsDataTable()
ForiAsInteger=firstControlIDTolastControlID

15 of20

'Readinthevaluesfortheproductnameandunitprice
DimproductNameAsString=CType(InsertingInterface.FindControl_
("ProductName"+i.ToString()),TextBox).Text.Trim()
DimunitPriceAsString=CType(InsertingInterface.FindControl_
("UnitPrice"+i.ToString()),TextBox).Text.Trim()
'EnsurethatifunitPricehasavalue,sodoesproductName
IfunitPrice.Length>0AndAlsoproductName.Length=0Then
'Displayawarningandexitthiseventhandler
StatusLabel.Text="Ifyouprovideaunitpriceyoumustalso
includethenameoftheproduct."
StatusLabel.Visible=True
ExitSub
EndIf
'Onlyaddtheproductifaproductnamevalueisprovided
IfproductName.Length>0Then
'AddanewProductsRowtotheProductsDataTable
DimnewProductAsNorthwind.ProductsRow=products.NewProductsRow()
'Assignthevaluesfromthewebpage
newProduct.ProductName=productName
newProduct.SupplierID=Convert.ToInt32(Suppliers.SelectedValue)
newProduct.CategoryID=Convert.ToInt32(Categories.SelectedValue)
IfunitPrice.Length>0Then
newProduct.UnitPrice=Convert.ToDecimal(unitPrice)
EndIf
'Addany"default"values
newProduct.Discontinued=False
newProduct.UnitsOnOrder=0
products.AddProductsRow(newProduct)
EndIf
Next
'Ifwereachhere,seeiftherewereanyproductsadded
Ifproducts.Count>0Then
'Addthenewproductstothedatabaseusingatransaction
DimproductsAPIAsNewProductsBLL()
productsAPI.UpdateWithTransaction(products)
'Rebindthedatatothegridsothattheproducstjustaddedaredisplayed
ProductsGrid.DataBind()
'Displayaconfirmation(don'tusetheWarningCSSclass,though)
StatusLabel.CssClass=String.Empty
StatusLabel.Text=String.Format(_
"{0}productsfromsupplier{1}havebeen"&_
"addedandfiledundercategory{2}.",_
products.Count,Suppliers.SelectedItem.Text,Categories.SelectedItem.Text)
StatusLabel.Visible=True
'Reverttothedisplayinterface
ReturnToDisplayInterface()
Else
'Noproductssupplied!

16 of20

StatusLabel.Text=
"Noproductswereadded.Pleaseenterthe"&_
"productnamesandunitpricesinthetextboxes."
StatusLabel.Visible=True
EndIf
EndSub

TheeventhandlerstartsbyensuringthatthePage.IsValid propertyreturnsavalueofTrue.IfitreturnsFalse,
thenthatmeansoneormoreoftheCompareValidatorsarereportinginvaliddatainsuchacasewedonotwantto
attempttoinserttheenteredproductsorwellendupwithanexceptionwhenattemptingtoassigntheuserentered
unitpricevaluetotheProductsRowsUnitPrice property.
Next,anewProductsDataTable instanceiscreated(products).AFor loopisusedtoiteratethroughtheproduct
nameandunitpriceTextBoxesandtheText propertiesarereadintothelocalvariables productName and
unitPrice.Iftheuserhasenteredavaluefortheunitpricebutnotforthecorrespondingproductname,the
StatusLabel displaysthemessageIfyouprovideaunitpriceyoumustalsoincludethenameoftheproduct and
theeventhandlerisexited.
Ifaproductnamehasbeenprovided,anewProductsRow instanceiscreatedusingtheProductsDataTables
NewProductsRow method.ThisnewProductsRow instancesProductName propertyissettothecurrentproduct
nameTextBoxwhiletheSupplierID andCategoryID propertiesareassignedtotheSelectedValue propertiesof
theDropDownListsintheinsertinginterfacesheader.Iftheuserenteredavaluefortheproductsprice,itis
assignedtotheProductsRow instancesUnitPrice propertyotherwise,thepropertyisleftunassigned,whichwill
resultinaNULL valuefor UnitPrice inthedatabase.Finally,theDiscontinued andUnitsOnOrder propertiesare
assignedtothehardcodedvaluesFalse and0,respectively.
AfterthepropertieshavebeenassignedtotheProductsRow instanceitisaddedtotheProductsDataTable.
AtthecompletionoftheFor loop,wecheckwhetheranyproductshavebeenadded.Theusermay,afterall,have
clickedtheAddProductsfromShipmentbeforeenteringanyproductnamesorprices.Ifthereisatleastone
productintheProductsDataTable,theProductsBLL classsUpdateWithTransaction methodiscalled.Next,
thedataisreboundtotheProductsGrid GridViewsothatthenewlyaddedproductswillappearinthedisplay
interface.TheStatusLabel isupdatedtodisplayaconfirmationmessageandtheReturnToDisplayInterface is
invoked,hidingtheinsertinginterfaceandshowingthedisplayinterface.
Ifnoproductswereentered,theinsertinginterfaceremainsdisplayedbutthemessageNoproductswereadded.
Pleaseentertheproductnamesandunitpricesinthetextboxesisdisplayed.
Figures13,14,and15showtheinsertinganddisplayinterfacesinaction.InFigure13,theuserhasenteredaunit
pricevaluewithoutacorrespondingproductname.Figure14showsthedisplayinterfaceafterthreenewproducts
havebeenaddedsuccessfully,whileFigure15showstwoofthenewlyaddedproductsintheGridView(thethird
oneisonthepreviouspage).

17 of20

Figure13:AProductNameisRequiredWhenEnteringaUnitPrice

Figure14:ThreeNewVeggiesHaveBeenAddedfortheSupplierMayumis

18 of20

Figure15:TheNewProductsCanBeFoundintheLastPageoftheGridView

Note:Thebatchinsertinglogicusedinthistutorialwrapstheinsertswithinthescopeoftransaction.To
verifythis,purposefullyintroduceadatabaselevelerror.Forexample,ratherthanassigningthenew
ProductsRow instancesCategoryID propertytotheselectedvalueintheCategories DropDownList,
assignittoavaluelikei*5.Herei istheloopindexerandhasvaluesrangingfrom1to5.Therefore,
whenaddingtwoormoreproductsinbatchinsertthefirstproductwillhaveavalid CategoryID value(5),
butsubsequentproductswillhaveCategoryID valuesthatdonotmatchuptoCategoryID valuesinthe
Categories table.TheneteffectisthatwhilethefirstINSERT willsucceed,subsequentoneswillfailwitha
foreignkeyconstraintviolation.Sincethebatchinsertisatomic,thefirstINSERT willberolledback,
returningthedatabasetoitsstatebeforethebatchinsertprocessbegan.

Summary
Overthisandtheprevioustwotutorialswehavecreatedinterfacesthatallowforupdating,deleting,andinserting
batchesofdata,allofwhichusedthetransactionsupportweaddedtotheDataAccessLayerintheWrapping
DatabaseModificationswithinaTransactiontutorial.Forcertainscenarios,suchbatchprocessinguserinterfaces
greatlyimproveenduserefficiencybycuttingdownonthenumberofclicks,postbacks,andkeyboardtomouse
contextswitches,whilealsomaintainingtheintegrityoftheunderlyingdata.
Thistutorialcompletesourlookatworkingwithbatcheddata.Thenextsetoftutorialsexploresavarietyof
advancedDataAccessLayerscenarios,includingusingstoredproceduresintheTableAdaptersmethods,
configuringconnection andcommandlevelsettingsintheDAL,encryptingconnectionstrings,andmore!
HappyProgramming!

AbouttheAuthor
ScottMitchell,authorofsevenASP/ASP.NETbooksandfounderof4GuysFromRolla.com,hasbeenworkingwith
MicrosoftWebtechnologiessince1998.Scottworksasanindependentconsultant,trainer,andwriter.Hislatest

19 of20

bookisSamsTeachYourselfASP.NET2.0in24Hours.Hecanbereachedatmitchell@4GuysFromRolla.com. or
viahisblog,whichcanbefoundat http://ScottOnWriting.NET.

SpecialThanksTo
Thistutorialserieswasreviewedbymanyhelpfulreviewers.LeadreviewersforthistutorialwereHiltonGiesenow
andSrenJacobLauritsen.InterestedinreviewingmyupcomingMSDNarticles?Ifso,dropmealineat
[email protected].

20 of20

You might also like