DBcontext.SaveChanges keeps returning 0 when updating - c#

I'm currently trying to do a really simple function that updates a category using LINQ. However dbContext.SaveChanges() always returns 0 rows updated even when I hardcode the categoryId to update which is really frustrating. I've already tried many forms of debugging but fail to find the problem. If anyone can help me figure out my dumb mistake, it would be greatly appreciated!
Things I've tried,
- Trying to see if row with that category_Id exists, always returns 1 which is correct.
var count = (from c in dbContext.RecipeCategories
where c.Category_Id == categoryToEdit
select c).Count();
Removing myCategory instead of trying to update it, works as well. It seems like only the update does not work.
dbContext.RecipeCategories.Remove(myCateogry);
My DALayer for category functions
public bool EditCategory(int categoryToEdit, RecipeCategory newCategoryInfo)
{
RecipeXchangeDBContext dbContext = new RecipeXchangeDBContext();
RecipeCategory myCategory = new RecipeCategory();
bool status = false;
myCategory = (from c in dbContext.RecipeCategories
where c.Category_Id == categoryToEdit
select c).First();
myCategory.Category_Name = newCategoryInfo.Category_Name;
myCategory.Description = newCategoryInfo.Description;
myCategory.CatGroup_Id = newCategoryInfo.CatGroup_Id;
try
{
if (dbContext.SaveChanges() == 1)
status = true;
else
status = false;
}
catch (InvalidOperationException ex)
{
status = false;
}
return status;
}
My attempt to call the function, always goes to else block, dbContext.SaveChanges() returns 0 with no exceptions thrown.
protected void btnEditCategory_Click(object sender, EventArgs e)
{
if (Request.QueryString["categoryId"] != null)
{
CategoryDAL categoryDAL = new CategoryDAL();
RecipeCategory myCategory = new RecipeCategory();
try
{
addDiv.Attributes["class"] = "hidden";
editDiv.Attributes["class"] = "display";
int categoryToEdit = Convert.ToInt32(Request.QueryString["categoryId"]);
myCategory.Category_Name = tbEditCategoryName.Text;
myCategory.Description = tbEditCategoryDescription.Text;
myCategory.CatGroup_Id = Convert.ToInt32(ddlEditCategoryGroupList.SelectedValue);
try
{
bool editStatus = categoryDAL.EditCategory(categoryToEdit, myCategory);
if (editStatus)
{
HttpContext.Current.Session["editStatus"] = "Successful";
Response.Redirect("~/Admin/ManageCategories.aspx");
}
else
{
lblEditStatus.Text = "Unable to update category, please try again";
lblEditStatus.CssClass = "alert-danger";
}
}
catch (Exception ex)
{
lblEditStatus.Text = Convert.ToString(ex);
lblEditStatus.CssClass = "alert-danger";
}
}
catch (Exception ex)
{
updateStatus.Attributes["class"] = "alert alert-info alert-dismissable fade in";
updateStatus.Visible = true;
lblStatus.Text = "Invalid categoryId.";
}
}
else
{
updateStatus.Attributes["class"] = "alert alert-info alert-dismissable fade in";
updateStatus.Visible = true;
lblStatus.Text = "Nothing to update.";
}
}
Update ** Seems like this is what's causing the problem. If the values of the form are prepopulated it doesn't seem to allow me to update the object. If I comment out the part where it populates the form. The update function works normally. Can anyone help me figure out why prepopulating the form causes the update to fail?
protected void Page_Load(object sender, EventArgs e)
{
// Populate Edit Fields
if (Request.QueryString["categoryId"] != null)
{
CategoryDAL categoryDAL = new CategoryDAL();
RecipeCategory myCategory = new RecipeCategory();
try
{
addDiv.Attributes["class"] = "hidden";
editDiv.Attributes["class"] = "display";
int categoryToGet = Convert.ToInt32(Request.QueryString["categoryId"]);
myCategory = categoryDAL.GetCategory(categoryToGet);
tbEditCategoryName.Text = myCategory.Category_Name;
tbEditCategoryDescription.Text = myCategory.Description;
ddlEditCategoryGroupList.SelectedValue = Convert.ToString(myCategory.CatGroup_Id);
}
catch(Exception ex)
{
updateStatus.Attributes["class"] = "alert alert-info alert-dismissable fade in";
updateStatus.Visible = true;
lblStatus.Text = "Could not get Category Info, please try again.";
}
}
}

Related

How to know when SQL query has finished

I´m trying to create a logic to update massively the column "Prices" from table "Products".
This logic is made, but in my C# code I send the command to the MS Access DB, and immediately I want to show the new results.
The problem is that the update query takes a few seconds to finish, and my C# instantaneously asks for the Select from Products, showing no changes.
The main question is how I can know when the update has finished to show the new results in the grid.
Here my code:
private void btnAceptar_Click(object sender, EventArgs e)
{
string operator;
int code = Convert.ToInt32(cmbcode .SelectedValue);
int material = Convert.ToInt32(cmbMaterial.SelectedValue);
int productType= Convert.ToInt32(cmbproductType.SelectedValue);
if (cmboperating.SelectedIndex == 0){ operator= "+"; }
else if (cmboperating.SelectedIndex == 1) { operator= "-"; }
else if (cmboperating.SelectedIndex == 2) { operator= "*"; }
else { operator= "/"; }
if(txtValoroperating.Text != "") { txtValoroperating.Text = (txtValoroperating.Text).Replace(",", "."); }
string operating = txtValoroperating.Text;
if(rdPrecioDeLista.Checked == true & cbTodasPiezas.Checked == true)
{
//Here is my problem
oProductsDAL.modifyPricesMassively(operating, operator);
txtValoroperating.Text = null;
fillGridProducts();
}
}
And oProductsDAL.modifyPricesMassively(operating, operator) does this:
public bool modifyPricesMassively(operating, operator)
{
if (operating!= "" & operator!= "")
{
return conexion.executeMethod("UPDATE Piezas SET Precio = Precio " +operator+" " +operating);
}
else
{
return false;
}
}
conexion.executeMethod does this:
public bool conexion.executeMethod(string strComando)
{
try
{
OleDbCommand Comando = new OleDbCommand();
Comando.CommandText = strComando;
Comando.Connection = this.establecerConexion();
Conexion.Open();
Comando.ExecuteNonQuery();
Conexion.Close();
return true;
}
catch (Exception ex)
{
MessageBox.Show("No se pudo establecer conexion con la base de datos" +ex);
return false;
}
}
I wish to show a progress bar or a gif loading icon.

Filter not changing on backspace press - radgridview - C#

In my program I have a text box and on text change a filter is applied to my RadGrid. However, on backspace the filter is not reapplied.
private void txt_search_TextChanged_1(object sender, EventArgs e)
{
try
{
CompositeFilterDescriptor searchFilter = new CompositeFilterDescriptor();
searchFilter.FilterDescriptors.Add(new FilterDescriptor("product", FilterOperator.Contains, txt_search.Text));
this.radGridView1.EnableFiltering = true;
this.radGridView1.MasterTemplate.Templates[0].EnableFiltering = true;
this.radGridView1.MasterTemplate.Templates[0].ShowFilteringRow = false;
this.radGridView1.MasterTemplate.ShowFilteringRow = false;
this.radGridView1.MasterTemplate.Templates[0].ShowTotals = true;
this.radGridView1.MasterTemplate.Templates[0].ShowFilterCellOperatorText = false;
if (txt_search.Text != "")
{
this.radGridView1.MasterTemplate.Templates[0].FilterDescriptors.Add(searchFilter);
}
foreach (GridViewRowInfo row in radGridView1.MasterTemplate.Rows)
{
if (row.ChildRows.Count == 0)
{
row.IsVisible = false;
}
else
{
row.IsVisible = true;
}
}
}
catch (Exception ex)
{
MessageBox.Show("Something went wrong searching the grid. Please try again and contact I.T. if this problem persists.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
Is there another function which needs to be generated that is applied on backspace?
This code is taken from another program I have which is written in VB.net and converted. The filter works as it should in the VB version and is reapplied when text is removed etc.
Any help appreciated.

How can I display a message to the user for this code?

I have a Boat Mooring reservations program, and currently, the way it works is, after you enter your name and click a button, the program gives you the next available mooring, there are 6 piers and 5 moorings per pier.
So, after all the moorings and piers are used up, the program crashes becuase there is nowhere for it to go, how can I make it so that the user gets a message box telling them, that there are no more spots available?
This is my code:
Button click:
private void button1_Click(object sender, EventArgs e)
{
var req = new BoatRequest();
req.Name = txtName.Text;
var client = new BoatReserveSoapClient();
BoatResponse response = client.ReserveMooring(req);
if (req != null)
{
Pierlbl.Text = response.Pier.ToString();
Mooringlbl.Text = response.Mooring.ToString();
Pierlbl.Visible = true;
Mooringlbl.Visible = true;
}
else
{
Pierlbl.Text = "Error Occured, please try again";
Mooringlbl.Text = "Error Occured, please try again";
}
}
The web method:
//Setting the max value for Piers and Moorings
public const int maxPiers = 6;
public const int maxMoorings = 30;
private static bool[,] reserveMooring = new bool[maxPiers, maxMoorings];
[WebMethod]
public BoatResponse ReserveMooring(BoatRequest req)
{
var res = new BoatResponse();
//if pierCalc set to 0, if smaller than maxPiers increment
for (int pierCalc = 0; pierCalc < maxPiers; pierCalc++)
{
//if mooringCalc set to 0, if smaller than maxMoorings increment
for (int mooringCalc = 0; mooringCalc < maxMoorings / maxPiers; mooringCalc++)
{
if (!reserveMooring[pierCalc, mooringCalc])
{
reserveMooring[pierCalc, mooringCalc] = true;
res.Pier = (Pier)pierCalc;
res.Mooring = (Mooring)mooringCalc;
return res;
}
}
}
return null;
}
This is where it crashes:
Pierlbl.Text = response.Pier.ToString();
Check that the response is not null, like this:
if (response != null)
{
Pierlbl.Text = response.Pier.ToString();
Mooringlbl.Text = response.Mooring.ToString();
Pierlbl.Visible = true;
Mooringlbl.Visible = true;
}
else
{
Pierlbl.Text = "Error Occured, please try again";
Mooringlbl.Text = "Error Occured, please try again";
}
You should just check if response != null and if it's the case, show the user a message.
In this example, req is never going to equal null. the response object is receiving the return value from your Web Service and would therefore the one to check for a null value in your if statement.
Like so:
if (response != null)
{
//Logic for success
}
else
{
//Logic for failure
}

How can I update Username and password in aspnet_Users table and other table was created by me tbl_users simultaneously?

I am Making a Web project and maintaining role management in this application. When I had been created web project then I defined role management in this application. When I create an user using createUser() function data stores in aspnet_Users,aspnet_Membership and other table that one has been created by me (tbl_users),stores all user information including some info of aspnet_Users,aspnet_Membership table. I am able to create data in these tables simultaneously but now I want to update and delete data in these tables simultaneously,how can it be possible please??..let me know.
Here is My code
protected void btn_signup_Click(object sender, EventArgs e)
{
try
{
// Create new user.
objuser.email=txt_email.Text;
objuser.password=txt_password.Text;
objuser.username = TextBox1.Text;
if (Membership.RequiresQuestionAndAnswer)
{
MembershipUser newUser =
Membership.CreateUser(objuser.email,objuser.password,
objuser.username);
}
else
{
MembershipUser newUser = Membership.CreateUser(
objuser.email,
objuser.password,
objuser.username);
int i = BusinessUser.BusinessRegisterUser(objuser);
if (i > 0)
{
Session["user_authenticate"] = "Verified";
Session["user_email"] = objuser.email;
Label1.Text = Session["user_email"].ToString();
login1.Style.Add("display", "none");
logout.Visible = true;
Response.Redirect("user_registration.aspx");
}
}
show_menu();
//Response.Redirect("login.aspx");
}
catch (MembershipCreateUserException ex)
{
WarningModal.Show();
lblWarning.Text = GetErrorMessage(ex.StatusCode);
pnlIssues.Visible = true;
}
catch (HttpException ex)
{
WarningModal.Show();
lblWarning.Text= ex.Message;
}
}
protected void loginUser_Authenticate(object sender, AuthenticateEventArgs e)
{
try
{
if (Membership.ValidateUser(loginUser.UserName, loginUser.Password))
{
Session["user_authenticate"] = "Verified";
e.Authenticated = true;
Session["user_email"] = loginUser.UserName;
objuser.email = Session["user_email"].ToString();
Label1.Text = Session["user_email"].ToString();
login1.Style.Add("display", "none");
logout.Visible = true;
}
else
{
e.Authenticated = false;
}
}
catch (Exception ex)
{
}
}
You could always put a trigger on the aspnet_membership table that cascades the update and delete actions to the tbl_user table.
http://technet.microsoft.com/en-us/library/ms189799.aspx

goto in c# and its usage

I have a subroutine. It comapares whether values are empty then doing something. For example, if they are empty, then warnings are raised.
The code works fine. But when value are not empty, the warnings are still pop out. Please help me to correct the logic.
Thanks.
private void btnNew_Click(object sender, EventArgs e)
{
try
{
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
goto Msg1;
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
goto Msg2;
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains((decimal)dr["SortOrder"]))
{
goto Msg3;
}
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
Msg1:
MessageBox.Show("Description is required.");
Msg2:
MessageBox.Show("Abbr is required.");
Msg3:
MessageBox.Show("Please select another one, this one is already used.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
From the above code, you see. if txtbox1 has some value, the program still displays Msg1. I want to avoid it.
Because labels are just labels, and code after them is executed sequentially.
Why can't you do just this:
try
{
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Description is required.");
return;
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Abbr is required.");
return;
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains((decimal)dr["SortOrder"]))
{
MessageBox.Show("Please select another one, this one is already used.");
return;
}
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
It's so much more readable.
Restructure your code to avoid goto - it is a relic and not much use in a properly object oriented codebase.
Returning from the method, throwing exceptions or building an errors dictionary are all better options than using goto.
For example, you can have a List<string> errors which you add to when you get an error condition.
If it is empty, no errors were encountered, if it isn't, there were.
This is a good case were goto is the wrong way to go. Use something like this instead.
private void btnNew_Click(object sender, EventArgs e)
{
try
{
bool error = false;
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Description is required.");
error = true;
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Abbr is required.");
error = true;
}
if (SortOrders.Contains(Convert.ToDecimal(numericOrder.Value)
{
MessageBox.Show("Please select another one, this one is already used.");
error = true;
}
if(error)
return;
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Edit
Just figured that my code didn't actually do the same as his first sample since it only displayed the first error no matter how many that occured. Updated my sample to accomodate for that.
I've always been taught to avoid goto like the plague, and it's something I've followed for years. I've never even considered it to be an option when writing code.
Thinking about it though, I did read an article a few years ago (which I can't find now) which said you could credibly use gotos only if you used it to jump down code, and not up: a rule that is stuck to here.
Check here for more info: Does anyone still use [goto] in C# and if so why?
There are better ways of using goto statement, for instacne using "return" (when used in the middle of a method), "break" and "continue". Have you ever used one of these?
private void btnNew_Click(object sender, EventArgs e)
{
try
{
var description = txtbox1.Text.Trim();
if (string.IsNullOrEmpty(description))
{
MessageBox.Show("Description is required.");
return;
}
var abbr = txtbox2.Text.Trim();
if (string.IsNullOrEmpty(abbr))
{
MessageBox.Show("Abbr is required.");
return;
}
var numericOrderValue = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains(numericOrderValue)
{
MessageBox.Show("Please select another one, this one is already used.");
return;
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = description;
dr["Abbr"] = abbr;
dr["SortOrder"] = numericOrderValue;
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnNew_Click(object sender, EventArgs e)
{
try
{
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Description is required.");
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Abbr is required.");
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains((decimal)dr["SortOrder"]))
{
MessageBox.Show("Please select another one, this one is already used.");
}
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Try this. It works.

Categories

Resources