As reviewed in the previous lesson, a data adapter allows
you to retrieve records from a database and make them available to your Windows
Forms Application. To make reading data of a database a little faster, the .NET
Framework provides a class used to read data from a database. For s SQL Server
database, this class is called SqlDataReader
Practical
Learning: Introducing the Data Reader
|
|
- Start Microsoft Visual Studio .NET or Visual C++ .NET
- Display the Server Explorer. Expand the Servers node, followed by the name
of the computer, followed by SQL Servers, followed by the name of the server
- Right-click the server and click New Database
- Set the New Data Name to CPAS and accept to use Windows NT
Integrated Security
- Click OK
- Under the name of the server in Server Explorer, expand the GCS node
- Right-click the Tables node and click New Table
- Create the table with the following columns (change only the indicated
information; anything that is not mentioned should be ignored and use the
default):
Column Name |
Data Type |
Length |
Allow Nulls |
Other Properties |
RepairOrderID |
int |
|
|
Primary Key
Identity: Yes |
OrderDate |
datetime |
|
Unchecked |
|
OrderTime |
datetime |
20 |
Unchecked |
|
CustomerName |
varchar |
|
Unchecked |
|
Address |
varchar |
|
|
|
City |
varchar |
|
|
|
State |
char |
2 |
|
|
ZIPCode |
varchar |
10 |
|
|
Make |
varchar |
20 |
Unchecked |
|
Model |
varchar |
32 |
Unchecked |
|
CarYear |
smallint |
5 |
Unchecked |
|
ProblemDescription |
text |
|
Unchecked |
|
PartName1 |
varchar |
|
|
|
UnitPrice1 |
decimal |
10 |
|
Default Value: 0.00
Scale: 2 |
Quantity1 |
tinyint |
3 |
|
Default Value: 0 |
SubTotal1 |
decimal |
10 |
|
Default Value: 0.00
Scale: 2 |
PartName2 |
varchar |
|
|
|
UnitPrice2 |
decimal |
10 |
|
Default Value: 0.00
Scale: 2 |
Quantity2 |
tinyint |
3 |
|
Default Value: 0 |
SubTotal2 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
PartName3 |
varchar |
|
|
|
UnitPrice3 |
decimal |
|
|
Scale: 2 |
Quantity3 |
tinyint |
|
|
Default Value: 0 |
SubTotal3 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
PartName4 |
varchar |
|
|
|
UnitPrice4 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
Quantity4 |
tinyint |
|
|
Default Value: 0 |
SubTotal4 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
PartName5 |
varchar |
|
|
|
UnitPrice5 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
Quantity5 |
tinyint |
|
|
Default Value: 0 |
SubTotal5 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
JobPerformed1 |
varchar |
80 |
|
|
JobPrice1 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
JobPerformed2 |
varchar |
80 |
|
|
JobPrice2 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
JobPerformed3 |
varchar |
80 |
|
|
JobPrice3 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
JobPerformed4 |
varchar |
80 |
|
|
JobPrice4 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
JobPerformed5 |
varchar |
80 |
|
|
JobPrice5 |
decimal |
|
|
Default Value: 0.00
Scale: 2 |
TotalParts |
decimal |
|
Unchecked |
Default Value: 0.00
Scale: 2 |
TotalLabor |
decimal |
|
Unchecked |
Default Value: 0.00
Scale: 2 |
TaxRate |
decimal |
|
Unchecked |
Default Value: 7.75
Scale: 2 |
TaxAmount |
decimal |
|
Unchecked |
Default Value: 0.00
Scale: 2 |
OrderTotal |
decimal |
|
Unchecked |
Default Value: 0.00
Scale: 2 |
Recommendations |
text |
|
|
|
- Save the table as RepairOrders and close it
- Create a new Windows Forms Application named CPAS2
- Design the form as follows (you could select (all) and copy the form from
lesson 7, paste it to this form and make the necessary changes):
|
Control |
Name |
Text |
Other Properties |
GroupBox |
|
Customer and Car Information |
|
Label |
|
First Name: |
|
TextBox |
txtFirstName |
|
|
Label |
|
Last Name: |
|
TextBox |
txtLastName |
|
|
Label |
|
Address |
|
TextBox |
txtAddress |
|
|
Label |
|
City: |
|
TextBox |
txtCity |
|
|
Label |
|
State: |
|
TextBox |
txtState |
|
|
Label |
|
ZIP Code: |
|
TextBox |
txtZIPCode |
|
TextAlign: Right |
Label |
|
Make / Model: |
|
TextBox |
txtMake |
|
|
TextBox |
txtModel |
|
|
Label |
|
Year: |
|
TextBox |
txtCarYear |
|
TextAlign: Right |
Label |
|
Problem Description: |
|
TextBox |
txtProblem |
|
|
GroupBox |
|
Parts Used |
|
Label |
|
Part Name |
|
Label |
|
Unit Price |
|
Label |
|
Qty |
|
Label |
|
Sub Total |
|
TextBox |
txtPartName1 |
|
|
TextBox |
txtPartUnitPrice1 |
0.00 |
TextAlign: Right |
TextBox |
txtPartQuantity1 |
0 |
TextAlign: Right |
TextBox |
txtPartSubTotal1 |
0.00 |
TextAlign: Right |
TextBox |
txtPartName2 |
|
|
TextBox |
txtPartUnitPrice2 |
0.00 |
TextAlign: Right |
TextBox |
txtPartQuantity2 |
0 |
TextAlign: Right |
TextBox |
txtPartSubTotal2 |
0.00 |
TextAlign: Right |
TextBox |
txtPartName3 |
|
|
TextBox |
txtPartUnitPrice3 |
0.00 |
TextAlign: Right |
TextBox |
txtPartQuantity3 |
0 |
TextAlign: Right |
TextBox |
txtPartSubTotal3 |
0.00 |
TextAlign: Right |
TextBox |
txtPartName4 |
|
|
TextBox |
txtPartUnitPrice4 |
0.00 |
TextAlign: Right |
TextBox |
txtPartQuantity4 |
0 |
TextAlign: Right |
TextBox |
txtPartSubTotal4 |
0.00 |
TextAlign: Right |
TextBox |
txtPartName5 |
|
|
TextBox |
txtPartUnitPrice5 |
0.00 |
TextAlign: Right |
TextBox |
txtPartQuantity5 |
0 |
TextAlign: Right |
TextBox |
txtPartSubTotal5 |
0.00 |
TextAlign: Right |
GroupBox |
|
Jobs Performed |
|
Label |
|
Job Description |
|
Label |
|
Price |
|
TextBox |
txtJobDescription1 |
|
|
TextBox |
txtJobPrice1 |
0.00 |
TextAlign: Right |
TextBox |
txtJobDescription2 |
|
|
TextBox |
txtJobPrice2 |
0.00 |
TextAlign: Right |
TextBox |
txtJobDescription3 |
|
|
TextBox |
txtJobPrice3 |
0.00 |
TextAlign: Right |
TextBox |
txtJobDescription4 |
|
|
TextBox |
txtJobPrice4 |
0.00 |
TextAlign: Right |
TextBox |
txtJobDescription5 |
|
|
TextBox |
txtJobPrice5 |
0.00 |
TextAlign: Right |
GroupBox |
|
Order Summary |
|
Button |
btnResetOrder |
Reset Order |
|
Button |
btnCalculateOrder |
Calculate Order |
|
Label |
|
Total Parts: |
|
TextBox |
txtTotalParts |
0.00 |
TextAlign: Right |
Label |
|
Total Labor: |
|
Text |
txtTotalLabor |
0.00 |
TextAlign: Right |
Label |
|
Tax Rate: |
|
TextBox |
txtTaxRate |
7.75 |
TextAlign: Right |
Label |
|
% |
|
Label |
|
Tax Amount: |
|
TextBox |
txtTaxAmount |
0.00 |
TextAlign: Right |
Label |
|
Total Order: |
|
TextBox |
txtTotalOrder |
0.00 |
TextAlign: Right |
Button |
btnSaveOrder |
Save this Order and Start New Order |
|
Button |
btnOpenOrder |
Open an Existing Order |
|
Label |
|
Recommendations |
|
TextBox |
txtRecommendations |
|
Multiline: True
ScrollBars: Vertical |
|
- Double-click the New Order/Reset button and implement its Click event as
follows:
private: System::Void btnReset_Click(System::Object * sender, System::EventArgs * e)
{
this->dtpOrderDate->Value = DateTime::Today;
this->dtpOrderTime->Value = DateTime::Now;
this->txtCustomerName->Text = S"";
this->txtAddress->Text = S"";
this->txtCity->Text = S"";
this->txtState->Text = S"";
this->txtZIPCode->Text = S"";
this->txtMake->Text = S"";
this->txtModel->Text = S"";
this->txtCarYear->Text = S"";
this->txtProblem->Text = S"";
this->txtPartName1->Text = S"";
this->txtUnitPrice1->Text = S"0.00";
this->txtQuantity1->Text = S"0";
this->txtSubTotal1->Text = S"0.00";
this->txtPartName2->Text = S"";
this->txtUnitPrice2->Text = S"0.00";
this->txtQuantity2->Text = S"0";
this->txtSubTotal2->Text = S"0.00";
this->txtPartName3->Text = S"";
this->txtUnitPrice3->Text = S"0.00";
this->txtQuantity3->Text = S"0";
this->txtSubTotal3->Text = S"0.00";
this->txtPartName4->Text = S"";
this->txtUnitPrice4->Text = S"0.00";
this->txtQuantity4->Text = S"0";
this->txtSubTotal4->Text = S"0.00";
this->txtPartName5->Text = S"";
this->txtUnitPrice5->Text = S"0.00";
this->txtQuantity5->Text = S"0";
this->txtSubTotal5->Text = S"0.00";
this->txtJobPerformed1->Text = S"";
this->txtJobPrice1->Text = S"0.00";
this->txtJobPerformed2->Text = S"";
this->txtJobPrice2->Text = S"0.00";
this->txtJobPerformed3->Text = S"";
this->txtJobPrice3->Text = S"0.00";
this->txtJobPerformed4->Text = S"";
this->txtJobPrice4->Text = S"0.00";
this->txtJobPerformed5->Text = S"";
this->txtJobPrice5->Text = S"0.00";
this->txtTotalParts->Text = S"0.00";
this->txtTotalLabor->Text = S"0.00";
this->txtTaxRate->Text = S"7.75";
this->txtTaxAmount->Text = S"0.00";
this->txtTotalOrder->Text = S"0.00";
this->txtRecommendations->Text = S"";
this->txtCustomerName->Focus();
}
|
- Under the above event, implement the follow method:
void CalculateOrder(void)
{
double part1UnitPrice, part1SubTotal, part2UnitPrice, part2SubTotal,
part3UnitPrice, part3SubTotal, part4UnitPrice, part4SubTotal,
part5UnitPrice, part5SubTotal, totalParts;
int part1Quantity = 0, part2Quantity = 0, part3Quantity = 0,
part4Quantity = 0, part5Quantity = 0;
double job1Price = 0.00, job2Price = 0.00, job3Price = 0.00,
job4Price = 0.00, job5Price = 0.00;
double totalLabor;
double taxRate, taxAmount, totalOrder;
// Don't charge a part unless it is clearly identified
if( this->txtPartName1->Text->Equals(S"") )
{
this->txtUnitPrice1->Text = S"0.00";
this->txtQuantity1->Text = S"0";
this->txtSubTotal1->Text = S"0.00";
part1UnitPrice = 0.00;
}
else
{
try {
part1UnitPrice = this->txtUnitPrice1->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Unit Price");
this->txtUnitPrice1->Text = S"0.00";
this->txtUnitPrice1->Focus();
}
try {
part1Quantity = this->txtQuantity1->Text->ToInt16(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Quantity");
this->txtQuantity1->Text = S"0";
this->txtQuantity1->Focus();
}
}
if( this->txtPartName2->Text->Equals(S"") )
{
this->txtUnitPrice2->Text = S"0.00";
this->txtQuantity2->Text = S"0";
this->txtSubTotal2->Text = S"0.00";
part2UnitPrice = 0.00;
}
else
{
try {
part2UnitPrice = this->txtUnitPrice2->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Unit Price");
this->txtUnitPrice2->Text = S"0.00";
this->txtUnitPrice2->Focus();
}
try {
part2Quantity = this->txtQuantity2->Text->ToInt16(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Quantity");
this->txtQuantity2->Text = S"0";
this->txtQuantity2->Focus();
}
}
if( this->txtPartName3->Text->Equals(S"") )
{
this->txtUnitPrice3->Text = S"0.00";
this->txtQuantity3->Text = S"0";
this->txtSubTotal3->Text = S"0.00";
part3UnitPrice = 0.00;
}
else
{
try {
part3UnitPrice = this->txtUnitPrice3->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Unit Price");
this->txtUnitPrice3->Text = S"0.00";
this->txtUnitPrice3->Focus();
}
try {
part3Quantity = this->txtQuantity3->Text->ToInt16(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Quantity");
this->txtQuantity3->Text = S"0";
this->txtQuantity3->Focus();
}
}
if( this->txtPartName4->Text->Equals(S"") )
{
this->txtUnitPrice4->Text = S"0.00";
this->txtQuantity4->Text = S"0";
this->txtSubTotal4->Text = S"0.00";
part4UnitPrice = 0.00;
}
else
{
try {
part4UnitPrice = this->txtUnitPrice4->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Unit Price");
this->txtUnitPrice4->Text = S"0.00";
this->txtUnitPrice4->Focus();
}
try {
part4Quantity = this->txtQuantity4->Text->ToInt16(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Quantity");
this->txtQuantity4->Text = S"0";
this->txtQuantity4->Focus();
}
}
if( this->txtPartName5->Text->Equals(S"") )
{
this->txtUnitPrice5->Text = S"0.00";
this->txtQuantity5->Text = S"0";
this->txtSubTotal5->Text = S"0.00";
part5UnitPrice = 0.00;
}
else
{
try {
part5UnitPrice = this->txtUnitPrice5->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Unit Price");
this->txtUnitPrice5->Text = S"0.00";
this->txtUnitPrice5->Focus();
}
try {
part5Quantity = this->txtQuantity5->Text->ToInt16(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Quantity");
this->txtQuantity5->Text = S"0";
this->txtQuantity5->Focus();
}
}
// Don't bill the customer for a job that is not specified
if( this->txtJobPerformed1->Text->Equals(S"") )
{
this->txtJobPrice1->Text = S"0.00";
job1Price = 0.00;
}
else
{
try {
job1Price = this->txtJobPrice1->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Job Price");
this->txtJobPrice1->Text = S"0.00";
this->txtJobPrice1->Focus();
}
}
if( this->txtJobPerformed2->Text->Equals(S"") )
{
this->txtJobPrice2->Text = S"0.00";
job2Price = 0.00;
}
else
{
try {
job2Price = this->txtJobPrice2->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Job Price");
this->txtJobPrice2->Text = S"0.00";
this->txtJobPrice2->Focus();
}
}
if( this->txtJobPerformed3->Text->Equals(S"") )
{
this->txtJobPrice3->Text = S"0.00";
job3Price = 0.00;
}
else
{
try {
job3Price = this->txtJobPrice3->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Job Price");
this->txtJobPrice3->Text = S"0.00";
this->txtJobPrice3->Focus();
}
}
if( this->txtJobPerformed4->Text->Equals(S"") )
{
this->txtJobPrice4->Text = S"0.00";
job4Price = 0.00;
}
else
{
try {
job4Price = this->txtJobPrice4->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Job Price");
this->txtJobPrice4->Text = S"0.00";
this->txtJobPrice4->Focus();
}
}
if( this->txtJobPerformed5->Text->Equals(S"") )
{
this->txtJobPrice5->Text = S"0.00";
job5Price = 0.00;
}
else
{
try {
job5Price = this->txtJobPrice5->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Job Price");
this->txtJobPrice5->Text = S"0.00";
this->txtJobPrice5->Focus();
}
}
part1SubTotal = part1UnitPrice * part1Quantity;
part2SubTotal = part2UnitPrice * part2Quantity;
part3SubTotal = part3UnitPrice * part3Quantity;
part4SubTotal = part4UnitPrice * part4Quantity;
part5SubTotal = part5UnitPrice * part5Quantity;
this->txtSubTotal1->Text = part1SubTotal.ToString(S"F");
this->txtSubTotal2->Text = part2SubTotal.ToString(S"F");
this->txtSubTotal3->Text = part3SubTotal.ToString(S"F");
this->txtSubTotal4->Text = part4SubTotal.ToString(S"F");
this->txtSubTotal5->Text = part5SubTotal.ToString(S"F");
totalParts = part1SubTotal + part2SubTotal + part3SubTotal +
part4SubTotal + part5SubTotal;
totalLabor = job1Price + job2Price + job3Price +
job4Price + job5Price;
try {
taxRate = this->txtTaxRate->Text->ToDouble(0);
}
catch(FormatException *)
{
MessageBox::Show(S"Invalid Tax Rate");
this->txtTaxRate->Text = S"7.75";
this->txtTaxRate->Focus();
}
double totalPartsAndLabor = totalParts + totalLabor;
taxAmount = totalPartsAndLabor * taxRate / 100;
totalOrder = totalPartsAndLabor + taxAmount;
this->txtTotalParts->Text = totalParts.ToString(S"F");
this->txtTotalLabor->Text = totalLabor.ToString(S"F");
this->txtTaxAmount->Text = taxAmount.ToString(S"F");
this->txtTotalOrder->Text = totalOrder.ToString(S"F");
}
|
- Return to the form. Click the first text box under Qty and, in the
Properties window, click the Events button
- In the Events section of the Properties window, generate the Leave event
and implement it as follows:
System::Void txtQuantity1_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the second text box under Qty. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtQuantity2_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the third text box under Qty. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtQuantity3_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the fourth text box under Qty. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtQuantity4_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the fifth text box under Qty. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtQuantity5_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the first text box under Price on the right side
of Job Performed. In the Events section of the Properties window, generate
the Leave event and implement it as follows:
System::Void txtJobPrice1_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the second text box under Price. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtJobPrice2_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the third text box under Price. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtJobPrice3_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the fourth text box under Price. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtJobPrice4_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Click the fifth text box under Price. In the Events
section of the Properties window, generate the Leave event and implement it
as follows:
System::Void txtJobPrice5_Leave(System::Object * sender, System::EventArgs * e)
{
CalculateOrder();
}
|
- Return to the form. Double-click the Save Order button and implement its
Click event as follows:
System::Void btnSaveOrder_Click(System::Object * sender, System::EventArgs * e)
{
String *strCustomerName = this->txtCustomerName->Text;
if( strCustomerName->Equals(S"") )
{
MessageBox::Show(S"You must provide a name for the customer");
return;
}
String *strOrderDate = this->dtpOrderDate->Value.ToString(S"d");
String *strOrderTime = this->dtpOrderTime->Value.ToString(S"t");
String *strNewRepairOrder = String::Concat(S"INSERT INTO RepairOrders(OrderDate, "
S"OrderTime, CustomerName, Address, "
S"City, State, ZIPCode, Make, Model, "
S"CarYear, ProblemDescription, PartName1, "
S"UnitPrice1, Quantity1, SubTotal1, "
S"PartName2, UnitPrice2, Quantity2, "
S"SubTotal2, PartName3, UnitPrice3, "
S"Quantity3, SubTotal3, PartName4, "
S"UnitPrice4, Quantity4, SubTotal4, "
S"PartName5, UnitPrice5, Quantity5, "
S"SubTotal5, JobPerformed1, JobPrice1, "
S"JobPerformed2, JobPrice2, JobPerformed3, "
S"JobPrice3, JobPerformed4, JobPrice4, "
S"JobPerformed5, JobPrice5, TotalParts, "
S"TotalLabor, TaxRate, TaxAmount, "
S"OrderTotal, Recommendations) "
S"VALUES('", strOrderDate, S"', '", strOrderTime,
S"', '", strCustomerName, S"', '", this->txtAddress->Text,
S"', '", this->txtCity->Text, S"', '", this->txtState->Text,
S"', '", this->txtZIPCode->Text, S"', '", this->txtMake->Text,
S"', '", this->txtModel->Text, S"', '", this->txtCarYear->Text,
S"', '", this->txtProblem->Text, S"', '", this->txtPartName1->Text,
S"', '", this->txtUnitPrice1->Text, S"', '", this->txtQuantity1->Text,
S"', '", this->txtSubTotal1->Text, S"', '", this->txtPartName2->Text,
S"', '", this->txtUnitPrice2->Text, S"', '", this->txtQuantity2->Text,
S"', '", this->txtSubTotal2->Text, S"', '", this->txtPartName3->Text,
S"', '", this->txtUnitPrice3->Text, S"', '", this->txtQuantity3->Text,
S"', '", this->txtSubTotal3->Text, S"', '", this->txtPartName4->Text,
S"', '", this->txtUnitPrice4->Text, S"', '", this->txtQuantity4->Text,
S"', '", this->txtSubTotal4->Text, S"', '", this->txtPartName5->Text,
S"', '", this->txtUnitPrice5->Text, S"', '", this->txtQuantity5->Text,
S"', '", this->txtSubTotal5->Text, S"', '", this->txtJobPerformed1->Text,
S"', '", this->txtJobPrice1->Text, S"', '", this->txtJobPerformed2->Text,
S"', '", this->txtJobPrice2->Text, S"', '", this->txtJobPerformed3->Text,
S"', '", this->txtJobPrice3->Text, S"', '", this->txtJobPerformed4->Text,
S"', '", this->txtJobPrice4->Text, S"', '", this->txtJobPerformed5->Text,
S"', '", this->txtJobPrice5->Text, S"', '", this->txtTotalParts->Text,
S"', '", this->txtTotalLabor->Text, S"', '", this->txtTaxRate->Text,
S"', '", this->txtTaxAmount->Text, S"', '", this->txtTotalOrder->Text,
S"', '", this->txtRecommendations->Text, S"');");
System::Data::SqlClient::SqlConnection *conDatabase = new
System::Data::SqlClient::SqlConnection(
S"Data Source=(local);Database='CPAS';Integrated Security=yes");
System::Data::SqlClient::SqlCommand *cmdDatabase = new
System::Data::SqlClient::SqlCommand(strNewRepairOrder, conDatabase);
conDatabase->Open();
cmdDatabase->ExecuteNonQuery();
conDatabase->Close();
}
|
- Return to the form. Double-click the Close button and implement its Click
event as follows:
System::Void btnClose_Click(System::Object * sender, System::EventArgs * e)
{
Close();
}
|
- Execute the application and create a repair order. Here is an example:
- Save the order
- Close the form and return to your programming environment
In Lesson 7, we saw that the .NET
Framework provided XML-supported classes used to read from, and write to, an XML
file going forth but without back. To support a unidirectional approach to
reading data from a SQL Server database, the .NET Framework provides the SqlDataReader.
This class reads data in a top-down direction without referring back to a record
it passed already:
In other words, the SqlDataReader reads the first
record, moves down, reads the second record, moves down, and so on, until it
gets to the last record. Once it has passed a record, it doesn't and cannot
refer back to it.
To create a data reader, you can declare a pointer to SqlDataReader.
This class doesn't have a constructor. This means that, to use it, you must
(directly) specify where it would read its data. To provide data to the reader,
the SqlCommand class is equipped with the ExecuteReader() method
that is overloaded with two versions. The simplest version of this method uses
the following syntax:
public: SqlDataReader* ExecuteReader();
Based on this, before using a data reader, you should first
create a command that would specify how data would be acquired. Once the data is
reader, you can pass it to the data reader by assigning the result of a call to
a SqlCommand::ExecuteReader() method to a SqlDataReader object.
Once data is supplied to the reader, you can access it, one
record at a time, from top to bottom. To access data that the reader acquired,
you can call its Read() method whose syntax is:
public: virtual bool Read();
As you can see, the Read() method simply reads a
record and moves on. When reading the records of a table, as mentioned already
many times, the data reader reads one record at a time and moves to the next.
Before moving to the next record, you can access the values stored in the
current record. To help with this, the columns of the table being read are
stored in a collection and each column can be referred to with a numeric index.
The first column has an index of 1. The second column has an index of 2, and so
on. To retrieve the actual data stored in a column, you may need to know the
type of information that column is holding so you can read it accurately.
Depending on the data type that a column was created with,
you can access it as follows:
If the column holds the following data type |
Use the following method |
System::Data::SqlTypes Equivalent |
bit |
GetBoolean() |
|
GetSqlBoolean() |
char, nchar |
GetChar() |
|
GetSqlChar() |
varchar, nvarchar |
GetString() |
|
GetSqlString() |
text, ntext |
GetString() |
|
GetSqlString() |
binary, varbinary |
GetBinary() |
|
GetSqlBinary() |
decimal |
GetDecimal() |
GetDouble() |
GetSqlDecimal() |
float |
GetFloat() |
|
GetSqlSingle() |
int |
GetInt32() |
|
GetSqlInt32() |
money, smallmoney |
GetDecimal() |
|
GetSqlDecimal() |
bigint |
GetInt64() |
|
GetSqlInt64() |
datetime, smalldatetime |
GetDateTime() |
|
GetSqlDateTime() |
smallint, tinyint |
GetInt16() |
GetByte() |
GetSqlInt16() |
When using one of the Get... or GetSql... methods, the
compiler doesn't perform any conversion. This means that, before sending the
data, you have two responsibilities. First you must convert the value read to
the appropriate (and probably exact) format. For example, if you read a natural
number from a column created with the tinyint data type, even though C++
allows a short to be implicitly converted to an int, the compiler
you use for your application would not perform or assume the conversion: the
value of a column created with tinyint must be read with GetByte()
or GetSqlByte() and trying to use GetInt32() or GetSqlInt32()
would throw an error.
|
|