Check if record already exists within the database - c#

I have a program that allows users to enter in movies and details about that movie and store them in a database. I have the database being displayed in my C# program and the user can select one of the rows and the information from that row will be put into the text box it corresponds to, for example the Title will go in the title text box and so on. what I want to do is stop the user hitting the submit button and putting the same record in the database.
Any help would be appreciated
Submit button:
private void btnSubmit_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtTitle.Text) || string.IsNullOrWhiteSpace(txtRunTime.Text))
{
MessageBox.Show("Fill in all the required fields");
}
else
{
if (lstStatus.SelectedIndex == 0)
{
Status = "Watched";
}
else
{
Status = "Not Watched";
}
if (lstType.SelectedIndex == 0)
{
Type = "Movie";
}
else
{
Type = "TV Show";
}
con.Open();
SqlCommand cmd = new SqlCommand("insert into dbo.Movies(Title, Genre, RunTime, Type, Status) values('"+txtTitle.Text+"','"+txtGenre.Text+"','"+txtRunTime.Text+"','"+Type+"','"+Status+"')", con);
cmd.ExecuteNonQuery();
MessageBox.Show("Data transferred into the database!");
con.Close();
txtTitle.Text = "";
txtRunTime.Text = ""; /
}
}
Code when selecting a row:
private void DataGridMovies_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if(DataGridMovies.CurrentRow.Index == DataGridMovies.Rows.Count - 1)
{
MessageBox.Show("Empty row selected"); // Display a message to the user
}
else
{
ID = Convert.ToInt32(DataGridMovies.Rows[e.RowIndex].Cells[0].Value.ToString());
txtTitle.Text = DataGridMovies.Rows[e.RowIndex].Cells[1].Value.ToString();
txtGenre.Text = DataGridMovies.Rows[e.RowIndex].Cells[2].Value.ToString();
txtRunTime.Text = DataGridMovies.Rows[e.RowIndex].Cells[3].Value.ToString();
if (DataGridMovies.Rows[e.RowIndex].Cells[4].Value.ToString() == "Movie")
{
lstType.SelectedIndex = 0;
}
else
{
lstType.SelectedIndex = 1;
}// End of IF ELSE Statement
if (DataGridMovies.Rows[e.RowIndex].Cells[5].Value.ToString() == "Watched")
{
lstStatus.SelectedIndex = 0;
}
else
{
lstStatus.SelectedIndex = 1;
}// End of IF ELSE Statement
}//End of IF statement

You need to use sql parameters or your sql database can be hacked.
You can read about that here:
https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=netframework-4.8
cmd.Parameters.AddWith(name, value)
Determine if the record exists. If it does not you are adding it with insert. If not you update the record instead.
Depending on the process power you have at your disposal you might also look into autocomplete. This can hide the fact they are just updating a record you already "found".
https://www.grapecity.com/blogs/dynamic-autocomplete-c1textbox
Meta tagging and algorithms on the back end sometimes take care of duplicate entries.

Related

C# PostBack Issue

I'm having some issues with posting back a RowCommand from a GridView. Not sure if my logic is correct so if somebody could point out where I am going wrong that would be great.
It seems there are lot of similar problems but none of the solutions have a default set of results in the gridview then rebinded with search results like this scenario.
The problem is when the RowCommand is fired I have the wrong result. On default load the button works correctly but if I search for customers and then use the RowCommand, the page posts back and rebinds the grid with the default customers always sending me to the wrong customer.
Page Load: Fill GridView with logged in users default clients
Search Box: Search companies entire client list and repopulate gridview
RowCommand: Send users to the customer
Postback:
if(!IsPostBack)
{
//Check if user logged in
User A_User = new User();
if(!A_User.Check_Logged_In())
{
if(A_User.Should_Redirect(System.IO.Path.GetFileName(Request.PhysicalPath)))
{
//Redirect user to login page
Response.Redirect(A_User.Login_Page());
}
}
//Modify nav buttons
HtmlGenericControl nav = (HtmlGenericControl)this.Page.Master.FindControl("UserPanel").FindControl("li_nav_address_book");
nav.Attributes["class"] = "active";
//Load logged in users customers
BindGrid(false);
}else
{
//Check for request
if(Request.Params["__EVENTTARGET"] != null)
{
//Check for search string
if(Request.Params["__EVENTTARGET"].ToString().Contains("SearchCustomers"))
{
//Load customers by search results
BindGrid(true);
}
//else
//{
// if(Request.Params["__EVENTTARGET"].ToString().Contains("btn2"))
// {
// Console.WriteLine("SENDER: ", "btn2 RowCommand");
// BindGrid(true);
// }
//}
}
}
Search Button:
protected void btn_Search_Click(object sender, EventArgs e)
{
BindGrid(true);
}
Grid Binding:
private void BindGrid(bool Search)
{
if(!Search)
{
//Load customers by rep ID
Contacts Contact_Manager = new Contacts();
gvCustomers.DataSource = null;
DataSet dsCustomers = Contact_Manager.Get_Customers_By_UserID((int)Session["User_ID"]);
DataTable tblCustomers = dsCustomers.Tables[0];
gvCustomers.DataSource = tblCustomers;
gvCustomers.DataBind();
}
else
{
//Load customers by search terms
Contacts Contact_Manager = new Contacts();
//Search by replacing spaces to do a rainbow database search as whole text instead of tags
DataSet dsCustomers = Contact_Manager.Get_Customers_By_Tags(tb_GetContacts.Text.Replace(" ", ""));
DataTable tblCustomers = dsCustomers.Tables[0];
gvCustomers.DataSource = null;
gvCustomers.DataSource = tblCustomers;
gvCustomers.DataBind();
}
}
RowCommand:
protected void gvCustomers_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if(e.CommandName == "Customer_Detail")
{
int Customer_ID = Convert.ToInt32(e.CommandArgument);
Response.Redirect("~/Customer/" + Customer_ID);
}
}

Implement check availability functionality on save button

I have created a link button in aspx form which check availablity of login email address and its functionality is as.
protected void lnkCheckAvailable_Click(object sender, EventArgs e)
{
SystemUserBL bl = new SystemUserBL(SessionContext.SystemUser);
ds = new DataSet();
bl.FetchForLoginEmailAddress(ds, txtLoginEmailAddress.Text);
if (ds.Tables[0].Rows.Count > 0)
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>This User Name is already in use by another user.</b>";
}
else
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>Congratulations! " + txtLoginEmailAddress.Text + " is available.</b>";
}
}
It's working fine when user will click on check availability link button. There is another button "Save" which saves the user information in the table. Now my issue is that if it displays "This User Name is already in use by another user." message the information is still saved in the database. Please tell me how to prevent this!!!
You can return true or false based on user name exists in database or not. You can create a method which will check user availability.
When user press save button you will call that method if method returns true it means user exists.
private bool CheckUserAvailability()
{
SystemUserBL bl = new SystemUserBL(SessionContext.SystemUser);
ds = new DataSet();
bl.FetchForLoginEmailAddress(ds, txtLoginEmailAddress.Text);
if (ds.Tables[0].Rows.Count > 0)
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>This User Name is already in use by another user.</b>";
return true;
}
else
{
valDuplicatePassword.Visible = true;
valDuplicatePassword.Text = "<b>Congratulations! " + txtLoginEmailAddress.Text + " is available.</b>";
return false;
}
}
You can also call this method on link click.
protected void lnkCheckAvailable_Click(object sender, EventArgs e)
{
CheckUserAvailability();
}
You will call this method on Save button if user don't exist than save information in database.
protected void Savebtn_Click(object sender, EventArgs e)
{
if(CheckUserAvailability() == false)
{
SaveUserInfoToDataBase();
}
}

DateTimePicker pain in the Bu.. I want to disable it if the previous conditions are not equal

I have a old time sheet application with historical data, the hr would like to view the old data once in a while, so i was given the task to build an c# application that would do so. first the user selects a paygroup drop down, chooses a pay group, based on the paygroup select the employees drop down get populated, then i have two text box one containing the min date and another containing you guessed it right a max date, Then i have two datetimepickers fromdate and to date. the datetimepicker gets its value from the mindate date box and max date text box, after all the items are selected the user clicks run report and the report is generated.
For a visual please click this -> picture
My Question is I want to set the visibility of the datetimepickers to false if there are no dates available like in this -> picture as you can see the dates dont change because the datetimepickers can't set itself equal to an empty string so to work around that i just want the user to not even see the datetimepickers
My Code that i tried:
private void mindateset() // fill the listbox of values of mindate and maxdate
{
if (Employee.SelectedValue != null)
{
if (Employee.SelectedValue.ToString().Trim().Length > 0)
{
try
{
using (MSSQL.SqlConnection connection = new MSSQL.SqlConnection(constr))
{
timepunchnew = new EtimeHistoryDataSet();
connection.Open();
using (MSSQL.SqlCommand command = new MSSQL.SqlCommand("SELECT MIN(TransDate) AS mindate, MAX(TransDate) AS maxdate FROM dbo.EtimePunchDetail WHERE (EmpID = #empid)", connection))
{
MSSQL.SqlParameter myminparam = new MSSQL.SqlParameter();
myminparam.Direction = ParameterDirection.Input;
myminparam.ParameterName = "#empid";
myminparam.Value = Employee.SelectedValue;
command.Parameters.Add(myminparam);
MSSQL.SqlDataAdapter myadapter = new System.Data.SqlClient.SqlDataAdapter();
myadapter.SelectCommand = command;
myadapter.Fill(timepunchnew, "Mindate");
AvailableMin.DataSource = timepunchnew.Mindate;
AvailableMin.DisplayMember = "mindate";
AvailableMax.DataSource = timepunchnew.Mindate;
AvailableMax.DisplayMember = "maxdate";
FromDate.MinDate = DateTime.Parse(AvailableMin.Text);
FromDate.Value = FromDate.MinDate;
if (FromDate.Value != FromDate.MinDate)
{
if (DialogResult.OK == MessageBox.Show("The Selected User Does Not Have Any FromDate"))
{
FromDate.Visible = false;
}
else
{
FromDate.Value = FromDate.MinDate;
FromDate.Visible = true;
}
}
ToDate.MaxDate = DateTime.Parse(AvailableMax.Text);
ToDate.Value = ToDate.MaxDate;
if (ToDate.Value != ToDate.MaxDate)
if (DialogResult.OK == MessageBox.Show("The Selected User Does Not Have Any FromDate"))
{
ToDate.Visible = false;
}
else
{
ToDate.Value = ToDate.MinDate;
ToDate.Visible = true;
}
}
}
ANY HELP WITH THIS WILL BE APPRECIATED, THIS IS THE LAST STEP IN MY PROJECT
I created two textboxes and placed it over the datetimepicker value and make it visible if there is not date available from the listbox :)
private void AvailableMin_SelectedIndexChanged(object sender, EventArgs e)
{
if (AvailableMin.Text == "")
{
textBox2.Visible = true;
textBox2.Text = "There are no to dates available for this particular user";
}
else
{
textBox2.Visible = false;
}
}
private void AvailableMax_SelectedIndexChanged(object sender, EventArgs e)
{
if (AvailableMax.Text == "")
{
textBox1.Visible = true;
textBox1.Text = "There are no to dates available for this particular user";
}
else
{
textBox1.Visible = false;
}
}

Sign up using Entity Framework

So i try to create a sign up method using entity framework and c#, this is the method :
//Button create new account
private void BtnSignUp_Click(object sender, EventArgs e)
{
IEnumerable<DriverAcount> list = from a in context.DriverAcounts select a;
foreach (var Ac in list)
{
if (TxBoxNewUserName.Text != Ac.Login)
{
if (TxtBoxPASS1.Text == TxBoxPass.Text)
{
Ac.Login = TxBoxNewUserName.Text;
Ac.Password = TxtBoxPASS1.Text;
context.DriverAcounts.Add(Ac);
MessageBox.Show("the account is create succefuly");
TxBoxNewUserName.Text = "";
TxtBoxPASS1.Text = "";
TxBoxPass.Text = "";
break;
}
else
{
MessageBox.Show("the two passwords didn't matched");
}
TxBoxNewUserName.Text = "";
TxtBoxPASS1.Text = "";
TxBoxPass.Text = "";
continue;
}
else
{
MessageBox.Show("this username is already exist, please choose another one");
TxBoxNewUserName.Text = "";
TxtBoxPASS1.Text = "";
TxBoxPass.Text = "";
break;
}
}
context.SaveChanges();
}
the problem is when i want to add a new user normally it should looking if it exist in database or not, but it didn't do it right, for example if we have two names in DB name1 and name2 and into the TextBox we have name2 it will add the name2 in DB even if it is already exist.
So plz if someone have an idea i will be very appreciate.
You need to look at your code again and understand exactly what it's doing - have you attached the debugger and stepped through it? The driver name will always be created on the first iteration of the foreach loop if the first name retrieved doesn't match the one in the text box. All the others will be ignored.
You can try this instead. There's no need querying for all the records (like you're doing at the moment) when you only want to check if one already exists.
private void BtnSignUp_Click(object sender, EventArgs e)
{
// This performs a case sensitive match on the login name, you'll need to change it if you want to ignore case
DriverAcount existingAccount = context.DriverAcounts.FirstOrDefault(d => d.Login == TxBoxNewUserName.Text);
if (existingAccount != null)
{
MessageBox.Show("This username already exists, please choose another one.");
}
else
{
if (TxtBoxPASS1.Text == TxBoxPass.Text)
{
Ac.Login = TxBoxNewUserName.Text;
Ac.Password = TxtBoxPASS1.Text;
context.DriverAcounts.Add(Ac);
// Only need to call this if you've made changes, so I've moved it here
context.SaveChanges();
MessageBox.Show("The account was created successfully");
}
else
{
MessageBox.Show("The two passwords didn't match each other.");
}
}
TxBoxNewUserName.Text = "";
TxtBoxPASS1.Text = "";
TxBoxPass.Text = "";
}

Entity Framework - Casting the retrieved Combobox value to string

Using Entity Framework, I have a Combobox showing a list of data retrieved from a database.
using System; //I removed the other using statements here to preserve space
namespace ExTea_BackEnd
{
public partial class frmAddBreakdown : Form
{
ExTeaEntities Breakdowns;
Breakdown_Type BreakdownTypes;
public frmAddBreakdown()
{
InitializeComponent();
}
private void cmbBreakdownType_SelectedIndexChanged(object sender, EventArgs e)
{
Breakdown_Type breakdownType = (Breakdown_Type)cmbBreakdownType.SelectedItem;
string selectedBreakdownTypeId = breakdownType.BrkdwnId;
IQueryable<Breakdown_Type> breakdownTypeQuery = from t in Breakdowns.Breakdown_Types
where t.BrkdwnId == selectedBreakdownTypeId
select t;
List<Breakdown_Type> selectedBreakdownId = breakdownTypeQuery.ToList();
if (selectedBreakdownId != null && selectedBreakdownId.Count > 0)
{
BreakdownTypes = selectedBreakdownId.First();
txtBreakdownId.Text = BreakdownTypes.BrkdwnId.ToString();
}
else
{
BreakdownTypes = null;
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
try
{
Breakdown newBreakdown = new Breakdown();
Breakdown_Type breakdownType = (Breakdown_Type)cmbBreakdownType.SelectedItem;
newBreakdown.BrkdwnType = breakdownType.ToString(); //this is where the error occurs
newBreakdown.MachineId = txtMachineId.Text.Trim();
newBreakdown.MachineType = txtMachineType.Text.Trim();
newBreakdown.ReportedDate = dtpDate.Value;
newBreakdown.JobStatus = "I";
Breakdowns.AddToBreakdowns(newBreakdown);
int rowsAffected = Breakdowns.SaveChanges();
if (rowsAffected > 0)
{
MessageBox.Show(rowsAffected + " records added!", "Save", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show("Error occured! " + ex.Message);
}
}
}
}
I'm trying to save the data in the form back to the database, an error occurs when trying to cast the value selected from the Combobox. Even when I've casted it to the right type, it does not save the selected value! But this,
I'm clueless on what I'm doing wrong here? Can anyone please tell me how to correct this?
Thank you.
newBreakdown.BrkdwnType = breakdownType.ToString();
Here you are just calling .ToString() Method of your object, so it is returning the Type Name, which you are able to view in database table record, for getting the BrkDwnType Property value you should change statement to
newBreakdown.BrkdwnType = breakdownType.BrkdwnType;
it should just be:
newBreakdown.BrkdwnType = cmbBreakdownType.SelectedItem.ToString();
no need for casting selectedItem if you just want the string value. From a design point of view, you should probably normalize your database and use an ID for breakDownType that references another table with BreakDown types.

Categories