How to check passport number exist or not? - c#

I want to check passport number exist or not ,
before I used this code to check if integer number exist or not ,
but passport number column in MSSQL type varchar(50).
what I tried
1- created stored procedure to read ID No :
create proc [dbo].[VALIDATE_PATIENT_IDNO]
#patient_id varchar(50)
as
select Patient_id from Patients
where Patient_id = #patient_id
2- I created this code in C# to validate id no exist or not :
public int? VALIDATE_PATIENT_IDNO(string patient_id)
{
DAL.DataAccessLayer DAL = new DAL.DataAccessLayer();
DataTable dt = new DataTable();
SqlParameter[] Param = new SqlParameter[1];
Param[0] = new SqlParameter("#patient_id", SqlDbType.VarChar,50);
Param[0].Value = patient_id;
dt = DAL.SelectData("VALIDATE_PATIENT_IDNO", Param);
DAL.close();
if (dt.Rows.Count > 0)
{
DataRow row = dt.Rows[0];
int? patientNumber = row.Field<int>("patient_id");
return patientNumber;
}
// return null otherwise
return null;
}
3- when type the id no or passport no when key down code :
private void textIDNO_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (string.IsNullOrEmpty(textIDNO.Text))
{
txtpcfileno.Focus();
}
else
{
var patientNumber = patient.VALIDATE_PATIENT_IDNO(textIDNO.Text); // int?
bool patientExists = patientNumber.HasValue;
if (patientExists == true)
{
MessageBox.Show("Id or Passport No Exist ", "ID EXIST", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
else
{
txtpcfileno.Focus();
}
}
}
}
4- I have error appeared in the code in step 2 :
Additional information: Specified cast is not valid.
int? patientNumber = row.Field<int>("patient_id");
How to change the code in step 2 and solve this error and check string value not int? ?

Letting the naming confusions (passportnumber vs patientid) aside, you probably don't want to return the found patientids (because you already know them, as they are part of your selection condition) but the count.
Furthermore, your patientid seems to be a string, yet in your result you try to cast this to an integer. That is not possible, thus the error.
You can try as follows:
create proc [dbo].[VALIDATE_PATIENT_IDNO]
#patient_id varchar(50)
as
select count(Patient_id) as patientcount from Patients
where Patient_id = #patient_id
Assuming that patient_id is the primary key of your table, this will either return 1 if a row with the given id exists or 0 if not.
Then you can do
int? patientNumber = row.Field<int>("patientcount");
and then
bool patientExists = patientNumber > 0;

Related

c#: How do create a null INT to use as an SQL Parameter

I'm declaring some variables then
I'm looping through some data using switch command if an attribute exists it gets assigned to the relevant variable
It is possible age will not be found the PostgreSQL Table reflects this
CREATE my_table(
id SERIAL PRIMARY KEY,
name varchar,
age INTEGER
);
The code snippet is giving me errors
Use of unassigned local variable 'age'
Argument 2: cannot convert from 'out int?' to 'out int'
Cannot convert type 'System.DBNull' to 'int'
How do I declare a null int and maybe assign a value if not pass it to the database as null?
IN pseudo code to show the gist of what I'm doing
// declared at the same level
string name = string.Empty;
int? age;
foreach (var p in Feature.Properties)
{
var Key = p.Key;
var Value = p.Value;
switch (Key.ToLower())
{
case "name":
{
name = Value;
break;
}
case "age":
{
// May not exist
// Err 2
int.TryParse(Value, out age);
break;
}
}
}
// Err 1 name is OK
Console.WriteLine(name + age);
using (var DB_con = new NpgsqlConnection(cs))
{
var sql = "INSERT INTO my_table (name,age )VALUES "+
"(#p_name, #p_age RETURNING id;";
using (var cmd = new NpgsqlCommand(sql, DB_con))
{
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.AddWithValue("#p_name", name);
// Err 3
cmd.Parameters.AddWithValue("#p_age", age ?? (int)DBNull.Value );
DB_con.Open();
var res = cmd.ExecuteScalar();
DB_con.Close();
}
}
I see two problems in your code:
you are trying to use int.TryParse() with nullable int.
you are trying to cast DBNull.Value into int.
please try something like this:
// declared at the same level
string name = string.Empty;
int? age;
foreach (var p in Feature.Properties)
{
var Key = p.Key;
var Value = p.Value;
switch (Key.ToLower())
{
case "name":
{
name = Value;
break;
}
case "age":
{
// May not exist
// Err 2
int parsedAge;
//try parsing into int, when sucessfull then assing value
if(int.TryParse(Value, out parsedAge))
{
age = parsedAge;
}
break;
}
}
}
// Err 1 name is OK
Console.WriteLine(name + age);
using (var DB_con = new NpgsqlConnection(cs))
{
var sql = "INSERT INTO my_table (name,age )VALUES "+
"(#p_name, #p_age RETURNING id;";
using (var cmd = new NpgsqlCommand(sql, DB_con))
{
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.AddWithValue("#p_name", name);
// Err 3
//remove casting into int
cmd.Parameters.AddWithValue("#p_age", age ?? DBNull.Value );
DB_con.Open();
var res = cmd.ExecuteScalar();
DB_con.Close();
}
}

Specified cast is not valid when I try to cast to (int?)

I have this code to save data to database
for (int i = 0; i < dt.Rows.Count; i++)
{
var row = dt.Rows[i];
await stock.AddProjectNeedsBoltsTest(Convert.ToInt32(row["Quantité"]),
(int?)row["Filetage"],
Convert.ToInt32(row["idProject"]),
(int?)row["idCategory"],
(int?)row["idType"]).ConfigureAwait(true);
}
and this the code behind AddProjectNeedsBoltsTest
public async Task AddProjectNeedsBoltsTest(int Quantity, int? Filetage, int IdProject, int? IdCategory, int? IdType)
{
DAL.DataAccessLayer DAL = new DAL.DataAccessLayer();
await Task.Run(() => DAL.Open()).ConfigureAwait(false);
SqlParameter[] param = new SqlParameter[5];
param[0] = new SqlParameter("#Quantity", SqlDbType.Int)
{
Value = Quantity
};
param[1] = new SqlParameter("#Filetage", SqlDbType.Int)
{
Value = Filetage.HasValue ? Filetage : (object)DBNull.Value
};
param[2] = new SqlParameter("#IdProject", SqlDbType.Int)
{
Value = IdProject
};
param[3] = new SqlParameter("#IdCategory", SqlDbType.Int)
{
Value = IdCategory.HasValue ? IdCategory : (object)DBNull.Value
};
param[4] = new SqlParameter("#IdType", SqlDbType.Int)
{
Value = IdType.HasValue ? IdType : (object)DBNull.Value
};
await Task.Run(() => DAL.ExcuteCommande("AddProjectNeedsBoltsTest", param)).ConfigureAwait(false);
DAL.Close();
}
and this is my stored procedure
CREATE PROCEDURE dbo.AddProjectNeedsBoltsTest
#Quantity int
,#Filetage int
,#IdProject int
,#IdCategory int
,#IdType int
AS
INSERT INTO [dbo].[ProjectNeedsBolts]
([Quantity]
,[Filetage]
,[IdProject]
,[IdCategory]
,[IdType])
VALUES
(#Quantity
,#Filetage
,#IdProject
,#IdCategory
,#IdType)
Now when I click on save button I get this error
An exception of type 'System.InvalidCastException' occurred in Smart Industrial Management.exe but was not handled in user code
Additional information: Specified cast is not valid.
On debugging on this line of code
(int?)row["Filetage"]
I get this error message
Cannot unbox 'row["Filetage"]' as a 'int?'
Update:This is my datatable
DataTable dt = new DataTable();
void CreateDataTable()
{
dt.Columns.Add("Quantité");
dt.Columns.Add("Filetage");
dt.Columns.Add("idProject");
dt.Columns.Add("idCategory");
dt.Columns.Add("idType");
gridControl1.DataSource = dt;
}
If I try with
dt.Columns.Add("Filetage", typeof(int?));
I get error message
DataSet does not support System.Nullable<>
Indeed, DataTable doesn't support int? - you'd add it as an int - with DataTable handing nullability separately. For the cast, there are two possibilities:
the value is DBNull
the value is something else - not an int; perhaps a long or a string
For 1 - just check whether the value is DBNull, and if so: don't try casting it to an int - handle the null yourself.
For 2 - you'd have to do your own parsing / conversion code, but frankly: it would be better to fix the database so that it is right
However, frankly: I am going to say: tools like Dapper make this just go away - no DataTable, no worries. You'd just use things like a List<ProjectNeedsBolts> for POCO:
public class ProjectNeedsBolts {
public int Quantity {get;set;}
public int IdType {get;set;}
}
(or int?, or whatever else you need), then get the library to do all the work for you:
await conn.ExecuteNonQueryAsync(
"AddProjectNeedsBoltsTest",
new { Quantity, Filetage, IdProject, IdCategory, IdType }
commandType: CommandType.StoredProcedure).ConfigureAwait(false);
or:
var data = await conn.QueryAsync<ProjectNeedsBolts>(
"your select sql",
new {...} // parameters
}).ConfigureAwait(false);

Passing DropDownList SelectedValue to SQL Query throws Input String was not in a Correct Format

I'm working on an ASP.NET webforms page that queries the database for a list of entries in the Study table. These entries are to be passed into the dropdownlist. When a study is selected from the dropdownlist, the studyID is to be passed to the GetResponses method to retrieve associated data from a stored procedure.
I receive Input String was not in a Correct Format with the following snippets:
private DataTable LoadStudies(int iStudyID )
{
ddlStudies.Items.Clear();
ddlStudies.SelectedValue = "0";
DataTable dt = new DataTable();
using (PROTOTYPING db = new PROTOTYPING(ConfigurationManager.ConnectionStrings["SQL"].ConnectionString))
{
var query = (from d in db.Studies
where d.StudyStatus == 0 //Closed...
orderby d.StudyName
select new
{
d.StudyName,
d.StudyID,
});
if (query.Count() > 0)
{
foreach (var a in query)
{
ddlStudies.Items.Add(new ListItem(a.StudyID.ToString()));
}
}
dt.Dispose();
DataView dv = new DataView(dt);
return dt;
}
}
The error is thrown on the Page_Load which is currently written as follows:
protected void Page_Load(object sender, EventArgs e)
{
int iUserID = 0;
if (Session["UserID"] == null)
{
Response.Redirect("Default.aspx");
}
iUserID = Convert.ToInt32(Session["UserID"]);
int iRole = 0;
iRole = Convert.ToInt32(Session["RoleID"]);
if (!Page.IsPostBack)
{
LoadStudies(Convert.ToInt32(ddlStudies.SelectedValue));
GetResponses(Convert.ToInt32(ddlStudies.SelectedValue));
ddlStudies.DataSource = LoadStudies(Convert.ToInt32(ddlStudies.SelectedValue));
ddlStudies.DataTextField = "StudyName";
ddlStudies.DataValueField = "StudyID";
ddlStudies.DataBind();
}
}
How do I resolve the error, which is thrown when assigning the dropdownlist's DataSource to the LoadStudies method?
ddlStudies.SelectedValue is not a valid integer value 0,1,2 etc.
I would wager a guess it's an empty string. Convert.ToInt32(""), which will throw the exception you are experiencing.
Interestingly Convert.ToInt32(null) will return a zero.
Try
Convert.ToInt32(string.IsNullOrWhiteSpace(ddlStudies.SelectedValue) ? null : ddlStudies.SelectedValue)

EF Code Structure in WinForms

I need some help with my code structure!
I have a form with some mandatory fields and some optionals.
I run some validation prior to saving the records on the database to make sure the data conforms to integrity rules. If its properly validated the data can then be saved. The problem sets with with my optional fields, comboboxes:
private async void SaveRecord()
{
if (ValidateForm())
{
int sucessReg = 0;
try
{
var memberRecord = new ClubMember()
{// Tab ID
Name = txtName.Text,
Surname = txtSurname.Text,
PassportNumber = (Int32)txtPasspt.text,
MaritalStatus = cboMarital.SelectedValue.ToString(),
Gender = cboGender.SelectedValue.ToString(),
DOB = dtpDob.Value,
DataEntrada = dtpDataEntra.Value,
Photo = ConvertImgToBinary(picBoxPhoto.Image),
Country = cboCountry.SelectedValue.ToString(),
};
ctxt.CubMember.Add(memberRecord);
sucessReg = await ctxt.SaveChangesAsync();
if (sucessReg == 1)
{
MessageBox.Show(this, "Record successfully saved.", "System Message");
}
}
catch (TargetInvocationException ex)
{
string err;
err = ex.ToString();
if (ex.InnerException != null)
{
err = ex.InnerException.Message;
}
MessageBox.Show(err);
}
}
}
Since some comboxes are optional and the selectedValue property is null at the moment of saving, the compiler throws the error "Object reference not set to an instance of an object."
The optional fields should go as is, that is, should be null on the database if the user didn't pick any item on the combo list.
So, I need a better way to structure my code in order to address this issue.
Does anybody have a brilliant idea?? :-)
Thanks in advance.
If you are using C#6 you could use ?. null conditional operator to check if ComboBox.SelectedValue is null before you use .ToString():
var memberRecord = new ClubMember()
{// Tab ID
Name = txtName.Text,
Surname = txtSurname.Text,
PassportNumber = (Int32)txtPasspt.text,
MaritalStatus = cboMarital.SelectedValue?.ToString(),
Gender = cboGender.SelectedValue?.ToString(),
DOB = dtpDob.Value,
DataEntrada = dtpDataEntra.Value,
Photo = ConvertImgToBinary(picBoxPhoto.Image),
Country = cboCountry.SelectedValue?.ToString(),
};
It is equivalent to:
var memberRecord = new ClubMember()
{// Tab ID
Name = txtName.Text,
Surname = txtSurname.Text,
PassportNumber = (Int32)txtPasspt.text,
MaritalStatus = cboMarital.SelectedValue == null ? null : cboMarital.SelectedValue.ToString(),
Gender = cboGender.SelectedValue == null ? null : cboGender.SelectedValue.ToString(),
DOB = dtpDob.Value,
DataEntrada = dtpDataEntra.Value,
Photo = ConvertImgToBinary(picBoxPhoto.Image),
Country = cboCountry.SelectedValue == null ? null : cboCountry.SelectedValue.ToString(),
};

Facing issues while converting stored procedure into entity framework function

I am new to entity framework. I have a procedure which save shipment data and I have to convert that procedure into entity framework function. For simple insert/update I am able to use entity framework but for this particular procedure I am facing issue.
In below procedure I have to update shipment table which have addressId, shipmenStatusId and serviceId as a foreign key. For particular shipment record if address is already exists then add existing address id in foreign key column otherwise first add new address into address table and then pick newly address id and update it into shipment address id column and same step for shipmentStatusType and service type.
Here is my procedure script.
CREATE PROCEDURE spSavePackage
#TrackingNbr VARCHAR(50),
#Carrier VARCHAR(10),
#PackageType VARCHAR(20) = NULL,
#ShippedDate DATETIME = NULL,
#ScheduledDate DATETIME = NULL,
#AddressLine1 VARCHAR(50)= NULL,
#AddressLine2 VARCHAR(50)= NULL,
#City VARCHAR(50) = NULL,
#State VARCHAR(2) = NULL,
#Country VARCHAR(2) = NULL,
#StatusDescription VARCHAR(50) = NULL
AS
BEGIN
DECLARE #AddressId int, #DeliveryStatusId int , #PackageId int
IF EXISTS (SELECT Id FROM tblPackages WHERE TrackingNr = #TrackingNbr AND Carrier = #Carrier)
BEGIN
IF EXISTS(SELECT Id FROM tblDeliveryAddress WHERE Address1 = #AddressLine1 AND Address2 = #AddressLine2
AND City = #City AND State = #State AND Country = #Country)
BEGIN
SELECT #AddressId = Id FROM tblDeliveryAddress WHERE Address1 = #AddressLine1 AND Address2 = #AddressLine2
AND City = #City AND State = #State AND Country = #Country
END
ELSE
BEGIN
SELECT #AddressId = MAX(Id) from tblDeliveryAddress
SET #AddressId = #AddressId + 1
INSERT INTO tblDeliveryAddress VALUES(#AddressId , #AddressLine1 , #AddressLine2 , #City , #State , #Country)
END
IF EXISTS (SELECT Id FROM tblDeliveryStatus WHERE Status = #StatusDescription)
BEGIN
SELECT #DeliveryStatusId = Id FROM tblDeliveryStatus WHERE Status = #StatusDescription
END
ELSE
BEGIN
SELECT #DeliveryStatusId = MAX(Id) FROM tblDeliveryStatus
SET #DeliveryStatusId = #DeliveryStatusId + 1
INSERT INTO tblDeliveryStatus VALUES(#DeliveryStatusId , #StatusDescription)
END
UPDATE tblPackages
SET DeliveryAddressID = #AddressId, DeliveryStatusId = #DeliveryStatusId,
ShippedDate = #ShippedDate , PackageType = #PackageType, ScheduledDate = #ScheduledDate
WHERE TrackingNr = #TrackingNbr AND Carrier = #Carrier
END
ELSE
BEGIN
SELECT #PackageId = MAX(Id) FROM tblPackages
SET #PackageId = #PackageId + 1
INSERT INTO tblPackages(Id , TrackingNr , Carrier) VALUES (#PackageId , #TrackingNbr , #Carrier)
END
END
For implementing functionality of this procedure I had created written following EF code.
public void UpdateShipments(List<Tuple<tblShipment, List<tblActivity>>> shipments)
{
tblShipment shipment = null;
var manager = ((IObjectContextAdapter)this._context).ObjectContext.ObjectStateManager;
foreach (var tuple in shipments)
{
shipment = tuple.Item1;
if (shipment.ConsigneeAddress != null)
{
shipment.ConsigneeAddressId = this.AddAddress(shipment.ConsigneeAddress).ID;
shipment.ConsigneeAddress = null;
}
else
{
shipment.ConsigneeAddressId = null;
shipment.ConsigneeAddress = null;
}
if (shipment.ShipperAddress != null)
{
shipment.ShipperAddressId = this.AddAddress(shipment.ShipperAddress).ID;
shipment.ShipperAddress = null;
}
else
{
shipment.ShipperAddressId = null;
shipment.ShipperAddress = null;
}
if (shipment.Service != null)
{
shipment.ServiceId = this.AddService(shipment.Service).ID;
shipment.Service = null;
}
else
{
shipment.ServiceId = null;
shipment.Service = null;
}
if (shipment.ShipmentStatusType != null)
{
shipment.ShipmentStatusId = this.AddStatusType(shipment.ShipmentStatusType).ID;
shipment.ShipmentStatusType = null;
}
else
{
shipment.ShipmentStatusId = null;
shipment.ShipmentStatusType = null;
}
this._context.Entry(shipment).State = System.Data.Entity.EntityState.Modified;
}
this._context.SaveChanges();
}
public tblAddressType AddAddressType(tblAddressType addressType)
{
tblAddressType tempAddressType = (from m in this._context.AddressTypes
where m.Type.ToUpper() == addressType.Type.ToUpper()
select m).FirstOrDefault();
if (tempAddressType == null)
{
tempAddressType = this._context.AddressTypes.Add(addressType);
this._context.SaveChanges();
}
return tempAddressType;
}
public tblAddress AddAddress(tblAddress address)
{
tblAddress tempAddress = (from m in this._context.Addresses
where m.AddressLine1.ToUpper() == address.AddressLine1.ToUpper() && m.AddressLine2.ToUpper() == address.AddressLine2.ToUpper() && m.City.ToUpper() == address.City.ToUpper()
&& m.StateProvinceCode.ToUpper() == address.StateProvinceCode.ToUpper() && m.CountryCode.ToUpper() == address.CountryCode.ToUpper()
select m).FirstOrDefault();
if (tempAddress == null)
{
address.AddressType = this.AddAddressType(address.AddressType);
address.AddressTypeId = address.AddressType.ID;
address.AddressType = null;
tempAddress = this._context.Addresses.Add(address);
this._context.SaveChanges();
}
return tempAddress;
}
After spending lots of time I found this way to implement it but I am not satisfied with this implementation. As I have to do lot's of hit for saving/updating shipment records which slowing the process. I need some optimized way to update shipment records so that for saving records I have to do only single database hit. I have multiple shipments record(records which is in collection) and I want single database hit to save records or 1 database hit to save one shipment records.
I tried to clarify my problems if any one facing issue to understand it then let me know. I am using c# as a programming language, sql server as a database and entity framework 6.0 as ORM.
Any help would be appreciated.
Thanks,
Awadhendra
I've had a similar problem in the past.
While it probably would be considered a hack by some others due to the nature of hard coding things that may change, if you also implement even simple integration tests (see later for an example) it is possible to keep track of such changes
Here is my solution
namespace ContextNamespace
{
public partial class ContextClass
{
public Task UpdateShipments(List<Tuple<tblShipment,
List<tblActivity>>> shipments)
{
return this.Database.ExecuteSqlCommandAsync("EXEC spSavePackage #p1 = #p1..",
new SqlParameter("#p1", shipments.???),....);
}
}
}
Along side this I have integration tests like this one, that their purpose is only to pass without exceptions -of course they can easily be fleshed out to include more proper checks
[TestMethod]
public async Task Sproc_Test()
{
//Create object
Context context = new Context();
await context.UpdateShipments(/*object*/);
}
An example of use in code is like this
public Task DoSomething(Object data)
{
return Context.UpdateShipments(data);
}

Categories

Resources