By Ian Johnston - 8/16/2010
I am trying to fill a BO with filtered data , can anyone tell me what I need to change ?public void pdt_data(string lic){ string s = "select * from truck where truck_license = "+lic;FillDataTable(s); }
|
By Edhy Rijo - 8/16/2010
Hi Ian,
I believe the problem is that the truck_license field type is varchar and if so you need to wrap the value of lic with quotations, something like this:
"select * from truck where truck_license = '"+ lic + "'";
Also much safer way to create your SQL statements is like this (VB):
Public Sub FindDuplicateTransactionItem(ByVal pFK_Items As Integer, ByVal pCardLotNo As String, ByVal pSerialNumber_Start As Integer, ByVal pCardQty As Integer)
'-- Establish Locals
Using cmd As New SqlCommand()
'-- Build the command
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "dbo.spFindDuplicateCardItem"
'-- Create and set the parameters
cmd.Parameters.AddWithValue("@pFK_Items", pFK_Items).SqlDbType = SqlDbType.Int
cmd.Parameters.AddWithValue("@pCardLotNo", pCardLotNo).SqlDbType = SqlDbType.VarChar
cmd.Parameters.AddWithValue("@pStartSerialNumber", pSerialNumber_Start).SqlDbType = SqlDbType.Int
cmd.Parameters.AddWithValue("@pCardQuantity", pCardQty).SqlDbType = SqlDbType.Int
Me.FillDataTable(cmd)
End Using
End Sub
Take a look at the help file for more samples.
|
By Ian Johnston - 8/16/2010
Thanks. Got it working once I got close enough to the screen to se the ' & " !
|
By Greg McGuffey - 8/16/2010
Ian,
Edhy's right on the money that you always want to use parametrized queries, instead building them by directly placing anything that is changeable directly into the string. Two reasons: to prevent SQL injection and to allow SQL server to cache the request, so it doesn't need to be compiled every time. It also means that you don't have to worry about how to get the data from a .net type into the correct form for the SQL statement.
|
By Ian Johnston - 8/20/2010
So can you show me how to add one parameter in C#. I get as far as SqlDbType and it is not offering int or Varchar as an option. Also I see the Also I don't know if the way I set it up is the problem but I have the followoing code in the leave event of a textbox: private void Trk_lic_Leave(object sender, EventArgs e){ this.truckBO1.Clear();this.truckBO1.pdt_data(Trk_lic.Text);if (this.truckBO1.Count > 0){ this.trkpdt.Text = this.truckBO1.truck_pdt.ToString();} } This runs the query on the BO and returns a value which is agssigned to the text value of a label if one is found. the problem I am having is that after this the CertFrm_FormEditingStateChanged event is triggered and the form starts back at tab order 0 and the only wayto get to the next textbox after this is to click into it, if you tab through the form you go back to zeo when tabbing out of this textbox.
|
By Edhy Rijo - 8/20/2010
Hi Ian,
I am not a C# developer but there are a lot places in the web which will help you converting from one language to the other.
Here my previous VB code converted to C# from http://www.developerfusion.com/tools/convert/vb-to-csharp/
public void FindDuplicateTransactionItem(int pFK_Items, string pCardLotNo, int pSerialNumber_Start, int pCardQty)
{
//-- Establish Locals
using (SqlCommand cmd = new SqlCommand()) {
//-- Build the command
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "dbo.spFindDuplicateCardItem";
//-- Create and set the parameters
cmd.Parameters.AddWithValue("@pFK_Items", pFK_Items).SqlDbType = SqlDbType.Int;
cmd.Parameters.AddWithValue("@pCardLotNo", pCardLotNo).SqlDbType = SqlDbType.VarChar;
cmd.Parameters.AddWithValue("@pStartSerialNumber", pSerialNumber_Start).SqlDbType = SqlDbType.Int;
cmd.Parameters.AddWithValue("@pCardQuantity", pCardQty).SqlDbType = SqlDbType.Int;
this.FillDataTable(cmd);
}
}
Now back to your problem, I believe what you want is just get the this.trkpdt.Text value based on the Trk_lic.Text value, if so, take a look in the help file on how to create an Scalar method in your BO that will return that trkpdt value.
What you are doing now is not going to work because you are clearing the PrimaryBusinessObject of the form which I assume is this.truckBO1 and then filling it with the data to get the Trk_lic.Text value. Spend some time with the SF help file which have pretty good examples of Scalar methods or search in the forums for more real examples. These are functionality that mostly every application will use and if you learn it well, then you can re-use whenever you need it.
|
By Greg McGuffey - 8/20/2010
Edhy is batting a 1000.
You don't want to refill the BO to get the value, just create a new method in the BO to do this simple task. This will leave the bound data in the UI alone. You would do something like this:
//-- This goes in the TruckBO...
public bool GetTruckPdt(string license, out string truckPdt)
{
//-- Establish a return var
bool dataFound = false;
//-- Set default return value if there is no value in db.
truckPdt = string.Empty;
//-- Build SQL string
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.AppendLine("Select truck_pdt");
sqlBuilder.AppendLine("From truck");
sqlBuilder.AppendLine("Where truck_license = @lic");
//-- Get data
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = sqlBuilder.ToString();
cmd.Parameters.AddWithValue("@lic", license).SqlDbType = SqlDbType.VarChar;
//-- Get Data, handle Null from database and nulls.
// This can return a DbNull.Value (i.e. a NULL from SQL) or it
// can return null (.NET) if there is no matching record in database
// (i.e. an empty recordset is returned). Thus before we can set the
// return variable, we have to test for these cases. It is also important
// to set a default value (as done above), in case no data is found
// in the database.
object result = this.ExecuteScalar(cmd);
if (result != DbNull.Value && result != null)
{
//-- By using an output variable (truckPdt) and a return variable
// (dataFound), I can somewhat simplify the
// client code because I can directly test
// the return value and get the value at the
// same time. It is equally valid to directly
// return the value (truckPdt) and then
// testing if it is a null or empty.
truckPdt = (string)result;
dataFound = true;
}
}
//-- Return if data was found.
return dataFound;
}
Once you have this in you TruckBO, you can use it like:
private void Trk_lic_Leave(object sender, EventArgs e)
{
//-- Get the data for this license.
string truckPdt = string.Empty;
if (this.truckBO1.GetTruckPdt(Trk_lic.Text, out truckPdt))
{
this.trkpdt.Text = truckPdt;
}
}
I hope this helps. Edhy is quite right that spending a bit time with the help file/examples also can help you understand the framework better.
|
By Ian Johnston - 8/21/2010
Thanks to both of you for your help.
|
By Greg McGuffey - 8/23/2010
Glad to help Ian.
|
By Ian Johnston - 8/29/2010
OK so I have written the following code to look up the truck license it works fine if there is only one numberpublic bool GetTrucklic(long carrier, out string truckLic){ //-- Establish a return varbool dataFound = false;//-- Set default return value if there is no value in db.truckLic = string.Empty;//-- Build SQL stringStringBuilder sqlBuilder = new StringBuilder();sqlBuilder.AppendLine( "Select count(*)");sqlBuilder.AppendLine( "From truck");sqlBuilder.AppendLine( "Where FK_customer = @carr");//-- Get datausing (SqlCommand cmd = new SqlCommand()){ cmd.CommandText = sqlBuilder.ToString(); cmd.Parameters.AddWithValue( "@carr", carrier).SqlDbType = SqlDbType.VarChar;//-- Get Data, handle Null from database and nulls.// This can return a DbNull.Value (i.e. a NULL from SQL) or it// can return null (.NET) if there is no matching record in database// (i.e. an empty recordset is returned). Thus before we can set the// return variable, we have to test for these cases. It is also important// to set a default value (as done above), in case no data is found// in the database.object result = this.ExecuteScalar(cmd);if (!DBNull.Value.Equals(result) && result != null){ //-- By using an output variable (truckPdt) and a return variable// (dataFound), I can somewhat simplify the// client code because I can directly test// the return value and get the value at the// same time. It is equally valid to directly// return the value (truckPdt) and then // testing if it is a null or empty.//truckPdt = result.ToString();if (result.Equals(1)){ dataFound = true;} else{ dataFound = false;} } } if (dataFound){ //-- Build SQL stringStringBuilder sqlBuilder2 = new StringBuilder();sqlBuilder2.AppendLine( "Select truck_license");sqlBuilder2.AppendLine( "From truck");sqlBuilder2.AppendLine( "Where FK_customer = @carr");//-- Get datausing (SqlCommand cmd2 = new SqlCommand()){ cmd2.CommandText = sqlBuilder2.ToString(); cmd2.Parameters.AddWithValue( "@carr", carrier).SqlDbType = SqlDbType.VarChar;//-- Get Data, handle Null from database and nulls.// This can return a DbNull.Value (i.e. a NULL from SQL) or it// can return null (.NET) if there is no matching record in database// (i.e. an empty recordset is returned). Thus before we can set the// return variable, we have to test for these cases. It is also important// to set a default value (as done above), in case no data is found// in the database.object result2 = this.ExecuteScalar(cmd2);if (!DBNull.Value.Equals(result2) && result2 != null){ //-- By using an output variable (truckPdt) and a return variable// (dataFound), I can somewhat simplify the// client code because I can directly test// the return value and get the value at the// same time. It is equally valid to directly// return the value (truckPdt) and then // testing if it is a null or empty.truckLic = result2.ToString(); dataFound = true;} } } //-- Return if data was found.return dataFound;} I am calling this from the enter event of the license textbox. The problem is if a company has more than one truck and therefore more than one license number. I am trying to call a browse dialog by repopulating a BO based on the carriers PK. private void Trk_lic_Enter(object sender, EventArgs e){ string trkLic = string.Empty;string trkLic2 = string.Empty;if (this.truckBO1.GetTrucklic(certificateBO1.FK_Customer2, out trkLic)){ this.Trk_lic.Text = trkLic; // this works and returns either one license number or blank if none exists.} else{ trkLic2 = this.getTrk_lic();this.Trk_lic.Text = trkLic2;} This sets up the browseDIalog and it shows all the license numbers for a carrier private string getTrk_lic(){ bool trk_lic = false;string ret_val = string.Empty; //-- Only show one panel, and put the browse results in the visible panelthis.browseDialogtruck.AdvancedOptions = false;this.browseDialogtruck.AllowHideResults = false;this.browseDialogtruck.AllowSearchFieldsButton = false;this.browseDialogtruck.SearchFields["FK_customer"].InitialValue = certificateBO1.FK_Customer2.ToString();this.browseDialogtruck.BusinessObjectToPopulate.Equals(truckBO2);//this.browseDialogtruck.OverrideSearchTableName.Equals(Tru);this.browseDialogtruck.ShowDialog(true);if (trk_lic){ return truckBO2.truck_license;} else{ return "";} } The problem is that I am back to the maintainence form it starts over again. My question is is there a way to use executeReader to return all the values and put them into the BrowseDialog?
|
By Ian Johnston - 8/30/2010
So in the light of day I modified the code to be private string getTrk_lic(){ //-- Only show one panel, and put the browse results in the visible panelthis.browseDialogtruck.AdvancedOptions = false;this.browseDialogtruck.AllowHideResults = false;this.browseDialogtruck.AllowSearchFieldsButton = false;this.browseDialogtruck.SearchFields["FK_customer"].InitialValue = certificateBO1.FK_Customer2.ToString();// '-- Show the browse dialog From the lookup control sample by Ivan// If CustomersBrowseDialog1.ShowDialog() = DialogResult.OK Then // Me.txtCode.Text = CustomersBO1.cust_pk.ToString // End If if (this.browseDialogtruck.ShowDialog(true).Equals(DialogResult.OK)){ return truckBO2.truck_license;} else{ return "";} } this now works and returns the value but the form still wants to start over, how do I get the focus back to the forms main BO (certificateBO1) and back to the textbox that calls this browsedialog?
|
By Ian Johnston - 8/30/2010
OK the fog is clearing. I had the tab control that textbox is on disabled in the FormEditingStaeChanged event - Don't know why but at some point it must have been a good idea! Code is now working great if there is only one value to assign it is assigned, if there are more than one value the BrowseDialog appears popualted with valid choices and choice selected is entered in the textbox or if there is no selection textbox is blank and allows entry as this may be a one time transaction using this license number.
|
By Edhy Rijo - 8/30/2010
Ian Johnston (08/30/2010) OK the fog is clearing.
Pretty good Ian, congratulations!!!
|
By Greg McGuffey - 8/30/2010
Glad you are getting it going. While programming can be frustrating, I love those "fog is clearing" moments.
|
By Jimmy D Cook - 3/31/2012
I was in search for this coding since long time back but you have cleared my doubts. You are too good.
|
By Edhy Rijo - 3/31/2012
Hi Jimmy,
Glad you found it useful. Fell free to keep searching the forums, there are a lot of good samples here for every level and if you can't find it, well, post it again here
|
|