Datagridview doesn't update - winforms

I work on windows form with entity framework 5.
I have a datagridview to record new sales and a save button to save changes on my entities.
But before saving the entities, I create some new stock objects. I have another gridview that looks at my stock but which is readonly.
My issues are the followings:
The sales and stock are updated in my database but while the gridview for sales show the new sales, the gridview for stock doesn't update to show the new stock
If there was an error on adding a new sale (say a foreign key error when inserting into the database) then after correcting the error and re-clicking on save, the sale is inserted once but the stock twice (or as many times as I had en error message)
I tried to create my stock through the createobject method rather than just with the new keywork but the problems remain.
Here is my saveButton click code
private void SaveButton_Click(object sender, EventArgs e)
{
try
{
var txnsGr = (IEnumerable<TransactionsGroupee>)this.achatsGroupeeBindingSource.DataSource;
foreach (var txnGr in txnsGr)
if (txnGr.EntityState == EntityState.Detached)
ge.TransactionsGroupees.AddObject(txnGr);
var localTransactions = ge.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Where(ent => ent.Entity is Transaction).Select(ent => ent.Entity as Transaction);
var achats = localTransactions.Where(x => x.TransactionsGroupee.sens == (int)Sens.Achat);
foreach (Transaction txn in achats)
{
for (int i = 0; i < txn.quantite; i++)
{
Stock stock = ge.CreateObject<Stock>();
stock.Agence1 = agence;
stock.Transaction = txn;
ge.Stocks.AddObject(stock);
}
}
ge.SaveChanges();
}
catch (Exception ex)
{
StringBuilder err = new StringBuilder(ex.Message);
if (ex.InnerException != null)
err.AppendLine().Append(ex.InnerException.Message);
MessageBox.Show(err.ToString());
}
}
Note that my sales (from two gridviews in a master/details configuration actually) where somehow detached and I have to attach them back first but hopefully this is not related to the issues described above.

Related

Unsure which join to use with with the following sql code

i have 2 tables. I am wanting to insert some values into 1 table. The fields i am updating is ingredient_Name, Ingredient_Amount and Recipe_ID.
Ingredient (Table 1)
Ingredient_Name|Ingredient_Amount|Recipe_ID
---------------|-----------------|--------- <---- Insert into here
Recipe (Table 2)
Recipe_Name|Recipe_ID
yummyRecipe|----1---- <-----Recipe_ID stored here
The form i am using has a comboBox which lists all Recipe_Names. So when i go to insert a row into ingredients i need to fetch the Recipe_ID from the Recipe table where i have selected the Recipe_Name in the comboBox. Then use this Recipe_ID for the ID in the Ingredients table.
I am not very familiar with JOINs and unsure how to work out what one to use and if i need to use one. Any help or ideas?
Sorry if this is too long winded.
Recipe ComboBox Code
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0; AttachDbFilename=C:\Users\Donald\Documents\Visual Studio 2013\Projects\DesktopApplication\DesktopApplication\Student_CB.mdf ;Integrated Security=True");
con.Open();
try
{
SqlDataAdapter da = new SqlDataAdapter("Select * FROM Recipe", con);
DataTable dt = new DataTable();
da.Fill(dt);
for (int i = 0; i < dt.Rows.Count; i++)
{
recipeCombo.Items.Add(dt.Rows[i]["Recipe_Name"]);
}
dt.Clear();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
con.Close();
You can set the ComboBox items using directly the DataSource and control which field you want to display using the DisplayMember property. Together with the ValueMember property you could write
using(SqlConnection con = new SqlConnection(....))
{
con.Open();
try
{
SqlDataAdapter da = new SqlDataAdapter("Select * FROM Recipe", con);
DataTable dt = new DataTable();
da.Fill(dt);
recipeCombo.DataSource = dt;
recipeCombo.DisplayMember = "Recipe_Name";
recipeCombo.ValueMember = "Recipe_ID";
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Now in the ComboBox_SelectedIndexChanged event (or everywhere you need to know the RecipeID you just have to write
if(recipeCombo.SelectedItem != null)
{
int recipeID = Convert.ToInt32(recipeCombo.SelectedValue);
... and use your value for insert without any JOIN
}
In whichever point you need, (for example in a SAVE button click event) add the following INSERT
if(recipeCombo.SelectedItem == null)
.... error message and return....
else
string sql = #"INSERT INTO Ingredient
(Ingredient_Name, Ingredient_Amount, Recipe_ID)
VALUES (#IngredientName, #IngredientFirstname, #RecipeID)";
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.Add("#IngredientName", SqlDbType.NVarChar).Value = ingredientTxt.Text);
cmd.Parameters.Add("#IngredientAmount", SqlDbType.Integer).Value = Convert.ToInt32(ingredientAmount.Text);
cmd.Parameters.Add("#RecipeID", SqlDbType.Integer).Value = Convert.ToInt32(recipeCombo.SelectedValue);
cmd.ExecuteNonQuery();
}
PS. Do not use AddWithValue - it is a shortcut with a lot of problems -
You do not need a JOIN in your case because you have only one table "Recipe" that contains the data you need to find "Recipe_ID". JOINs are used to "join" two tables.
If "Recipe_Name" is identical you can select the "Recipe_ID" where the "Recipe_Name" is equal to the selected value from the combobox then insert the new row to the "Ingredient" table.
INSERT INTO Ingredient SELECT #Ingredient_Name, #Ingredient_Amount, Recipe_ID FROM Recipe WHERE Recipe_ID = #myComboboxSelectedValue
Note: In this case Recipe_ID is redundant because you can remove it from your database and use Recipe_Name instead.
If "Recipe_Name" is not identical so you will need to fetch "Recipe_ID" with it and store it in the code-behind (if you do not want to show it to the user) and use it in your insert query.
By the way:
4. Whether using MYSQL or SQLSERVER the solution is the same, so "using .mdf" in the title of the question is irrelevant.
5. ".mdf" files are the extensions for SQLSERVER databases.

SQL Server 2008 changed table name bizarre behavior

I changed the name of one of my tables, then afterwards encoded some data then pulled it using a view to my surprise the data is not showing. I tried renaming it back to its original name with no luck the same thing is happening.
Then finally I tried retyping the data on one of the columns and then executed the view and there the data is finally showing now the problem arises I need to re encode the data on one of the column every time a data is inserted which is obviously not a good thing to do.
here is the code on how i added some data
tblcsv.Columns.AddRange(new DataColumn[7] { new DataColumn("unit_name", typeof(string)), new DataColumn("unit", typeof(string)), new DataColumn("adrress", typeof(string)), new DataColumn("latitude", typeof(string))
,new DataColumn("longitude" , typeof(string)) , new DataColumn("region" , typeof(string)) , new DataColumn("linkid" , typeof(string))});
string ReadCSV = File.ReadAllText(forex);
foreach (string csvRow in ReadCSV.Split('\n'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
tblcsv.Rows.Add();
int count = 0;
foreach (string FileRec in csvRow.Split(','))
{
tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
if (count == 5)
{
tblcsv.Rows[tblcsv.Rows.Count - 1][6] = link;
}
count++;
}
}
}
string consString = ConfigurationManager.ConnectionStrings["diposlConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(consString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
//Set the database table name
sqlBulkCopy.DestinationTableName = "dbo.FRIENDLY_FORCES";
//[OPTIONAL]: Map the Excel columns with that of the database table
sqlBulkCopy.ColumnMappings.Add("unit_name", "unit_name");
sqlBulkCopy.ColumnMappings.Add("unit", "unit");
sqlBulkCopy.ColumnMappings.Add("adrress", "adrress");
sqlBulkCopy.ColumnMappings.Add("latitude", "latitude");
sqlBulkCopy.ColumnMappings.Add("longitude", "longitude");
sqlBulkCopy.ColumnMappings.Add("region", "region");
sqlBulkCopy.ColumnMappings.Add("linkid", "linkid");
con.Open();
sqlBulkCopy.WriteToServer(tblcsv);
con.Close();
}
}
the column region is where i manually edited the data
Did the renaming of the table did something to my data?
Or am I just missing something?
Thank you

Search button losing datada

Afternoon,
I have a search button which searches the list of the users is either by IDnumber,Username or department.
I have 2 list view which the users clicks and it load the selected user to the second list view. now the problem is after u clicked users from listview1 and u went to type ID,Username or select department and click search...It clears all the users you selected and bring new users u where searching.
I want to be able to select the users and be able to search without losing my current selected users from the listview
my code ;
//search button
private void Searchbutton_Click(object sender, EventArgs e)
{
try
{
listView1.Items.Clear();
string sID = string.IsNullOrEmpty(txtUserID.Text) ? null : txtUserID.Text;
string sDepartment;
if (cboDepartment.SelectedItem != null)
{
sDepartment = cboDepartment.SelectedItem.ToString();
}
else
{
sDepartment = "";
}
oConnection = new SqlConnection(_connectionString);
oCommand = new SqlCommand(#"Select us.sFieldValue5, u.sUserName, d.sName, TB_USER_CUSTOMINFO.sFieldValue2
From TB_USER u(nolock)
left join [TB_USER_CUSTOMINFO] us(nolock) on us.nUserIdn = u.nUserIdn
left join TB_USER_CUSTOMINFO on u.nUserIdn = TB_USER_CUSTOMINFO.nUserIdn
left join TB_USER_DEPT d(nolock) on d.nDepartmentIdn = u.nDepartmentIdn
where u.sUserName like '%'+ISNULL(#UserName,u.sUserName)+'%'
and us.sFieldValue5 = isnull(#IDNumber,us.sFieldValue5)
and d.sDepartment like '%'+isnull(#Department,d.sDepartment)+'%'", oConnection);
oCommand.Parameters.AddWithValue("UserName", string.IsNullOrEmpty(txtUsername.Text) ? DBNull.Value : (object)txtUsername.Text);
oCommand.Parameters.AddWithValue("IDNumber", string.IsNullOrEmpty(txtUserID.Text) ? DBNull.Value : (object)txtUserID.Text);
oCommand.Parameters.AddWithValue("Department", string.IsNullOrEmpty(sDepartment) ? DBNull.Value : (object)sDepartment);
oConnection.Open();
oDataset = new System.Data.DataSet();
SqlDataReader oReader = oCommand.ExecuteReader();
while (oReader.Read())
{
ListViewItem item1 = new ListViewItem(oReader[1].ToString());
item1.SubItems.Add(oReader[2].ToString());
item1.SubItems.Add(oReader[3].ToString());
item1.SubItems.Add(oReader[0].ToString());
listView1.Items.AddRange(new ListViewItem[] {item1});
}
oReader.Close();
oConnection.Close();
}
//selected users
private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
if (e.Item.Checked == true)
{
ListViewItem l = listView1.Items[e.Item.Index];
int i = l.SubItems.Count;
string sValue1 = l.SubItems[1].Text;
string sValue2 = l.SubItems[2].Text;
string sValue3 = l.SubItems[3].Text;
ListViewItem item1 = new ListViewItem(l.SubItems[0].Text.ToString());
item1.SubItems.Add(sValue3);
item1.SubItems.Add(sValue2);
item1.SubItems.Add(sValue1);
listView2.Items.AddRange(new ListViewItem[] { (ListViewItem)l.Clone() });
}
else if (e.Item.Checked == false)
{
ListViewItem l = listView1.Items[e.Item.Index];
foreach (ListViewItem i in listView2.Items)
{
if (i.SubItems[0].Text == l.SubItems[0].Text.ToString())
{
listView2.Items.Remove(i);
}
}
}
}
ListView remember which ListViewItems were checked. As soon as you say Items.Clear(), all that knowledge is lost.
To solve your problem, you will need to remember which users were checked, do your refresh, then go through and mark each user as checked again.
To do those steps, you really need to separate your model from your view. Create a User model object to hold the actual data, then populate your ListView with data from your model. When the user does another search, update or refresh your model objects, then rebuild your view.
Doing this model/view separation is a little more work up front, but future generations of maintenance programmers will bless your name.
BTW, ObjectListView -- an open source wrapper around a .NET ListView -- makes creating a fully functional ListView from a list of model objects trivially easy.

How to know the order of update with Domain context SubmitChanges?

Suppose I have 3 entities generated from EF, say tab1, tab2 and tab3. In SL app, I call SubmitChanges to save data to DB, all changes will be process by WCF and EF automatically.
Question is: how can I know the order of Update operation in Database?
I need to know this because I have triggers on those tables and need to know the order of the updating.
One thing you can do is to override the PeristChangeSet() in your DomainService and manually control the order of saves. Just do nothing in your regular update/insert statements. Here's some pseudocode for a saving a document exmmple to explain my answer:
[Insert]
public void InsertDocument(MyDocument objDocument) { }
[Update]
public void UpdateDocument(MyDocument objDocument) { }
protected override bool PersistChangeSet()
{
try {
// have to save document first to get its id....
MyDocument objDocumentBeingSaved = null;
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is MyDocument)) {
var changedEntity = (MyDocument)CSE.Entity;
objDocumentBeingSaved = documentRepository.SaveDocument(changedEntity);
break; // only one doc
}
if (objDocumentBeingSaved == null)
throw new NullReferenceException("CreateDocumentDomainService.PersistChangeSet(): Error saving document information. Document is null in entity set.");
// save document assignments after saving document object
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is DocumentAssignment)) {
var changedEntity = (DocumentAssignment)CSE.Entity;
changedEntity.DocumentId = objDocumentBeingSaved.Id;
changedEntity.Id = documentRepository.SaveDocumentAssignment(objDocumentBeingSaved, changedEntity);
}
// save line items after saving document assignments
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is LineItem)) {
var changedEntity = (LineItem)CSE.Entity;
changedEntity.DocumentId = objDocumentBeingSaved.Id;
changedEntity.Id = documentRepository.SaveLineItem(objDocumentBeingSaved, changedEntity);
}
documentRepository.GenerateDocumentNumber(objDocumentBeingSaved.Id);
}
catch {
// ....
throw;
}
return false;
}

Dynamically add check box and records from database in javaFX 2.2 Table View

I am writing a client-server java FX application with a table View. I have a database in the server side and I want from the Client to load the table Columns and table Records from the db to a table View dynamically. So far I have found many hints, on how to do this successfully. The thing is that I want to add to the table a column 'select' which is a check box. Below is my code.
private void AddToTableRecordsFromDB(TabPane tp){
tableview = (TableView) tp.lookup("#table");
ObservableList<Object> data = null;
try {
String[] columnNames = (String[]) Login.Login.in.readObject();
ArrayList<ArrayList> al = (ArrayList<ArrayList>) Login.Login.in.readObject();
/**********************************
* TABLE COLUMN ADDED DYNAMICALLY *
**********************************/
TableColumn select = new TableColumn("Select");
select.setCellValueFactory(new PropertyValueFactory("invited"));
select.setCellFactory(new Callback<TableColumn<ObservableValue, Boolean>, TableCell<ObservableValue, Boolean>>() {
public TableCell<ObservableValue, Boolean> call(TableColumn<ObservableValue, Boolean> p) {
return new CheckBoxTableCell<ObservableValue, Boolean>();
}
});
tableview.getColumns().add(select);
for(int i=0 ; i<columnNames.length; i++){
//use non property style for making dynamic table
final int j = i;
TableColumn col;
col = new TableColumn(columnNames[i]);
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
#Override
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
tableview.getColumns().add(col);
}
/********************************
* Data added to ObservableList *
********************************/
data = FXCollections.observableArrayList();
for(int i=0 ; i<al.size(); i++){
ObservableList<ArrayList> row = FXCollections.observableArrayList(al.get(i));
data.add(row);
}
//FINALLY ADDED TO TableView
tableview.setItems(data);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Developer_Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
I took the CheckBoxTableCell class from the JavaFX2.0 Ensemble.
The database loads successfully in to the table view and also my 'select' column is created, but I can not see any check boxes in the rows.
Any help please ?
You say you are using "non property style" to add columns dynamically, and your table view made of list of list items. I guess there is no getInvited() method in those data structure model. However by setting select.setCellValueFactory(new PropertyValueFactory("invited")); the table column will look for that method. Set cell value factory with valid value.
EDIT: I didn't test but can you try the code below.
select.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> p) {
return new SimpleStringProperty(p.getValue().get(0).toString());
}
});
Note the get(0). Namely it would be better if readObject() returns at least 1 item. Another note is CheckBoxTableCell needs a Callback which returns ObservableProperty<Boolean> and binds bidirectionally so I think it is better to implement your own cell factory containing checkbox, regarding to your data model.

Resources