please I need help with the following scenario.
I have a binding list that has entity objects. I am passing the current entity object to a save form that is used to update the entity object passed as a parameter. This save form reads the properties of the entity object class and display controls accordingly. Each of these controls is bound to a property of the entity object. Whenever I change a control value, the corresponding entity property will be updated which will update the entity object in the entity list.
What I need is to apply the changes on the entity object in my save form only after an update button is clicked.
One way around is to make a copy of the entity object before passing it to the save form. But making a deep copy of an object is costly as far as I know.
Create a new class that will resemble the entity and will act as a buffer for the properties on the update form. When the user click's update read all the properties from the buffer class and pass them to the entity and then save it to DB.
Related
Current situation
I have a WPF application where I use MVVM and NHibernate. I have a master/detail window with a listbox with all my customers, and the selectedItem of the listbox is the object that is being used to display the customerdetails in the detailscreen.
In the detailscreen I have an add, edit, delete, save and an undo buttton. Everything works with the binding I've set up.
Problem
But for my undo button I was thinking of making a copy of the original Customer object so when I click the undo button the field will be resetted to the values from the original values. But in my customer object I have an Address object and with a shallow copy the 2 objects will keep the same reference to that object. So when I change a field from the Address object the original Customer address will also be changed. I was thinking of doing a deep copy of my Customer address but I can't make my object serializable (It's not in my control to change the Model objects)
Is there any way to do a deep copy without serialization?
Or is there some standard way to accomplish the behavior I want to achieve?
I would simply go back to the database and reload the customer object. That ensures that the data you're displaying is consistent with the data in the database and reduces the risk of concurrency issues.
Presently In my application , on click of grid row , i fill the control of the page with the grid row entries. I have a UPDATE button to save the changes . But even if the don't modify any control values and click on Update button , updation will be done with same values. that triggers a entry to log table .
How can I make the form to call the update only when the values of the controls are different than what is being loaded to them when i click grid.
UPDATE :
Application is not using any pattern like MVVM . the structure what is being followed is very slimier to win forms except the UI . For db interaction ADO.net . It was built already when i joined to this project & even I am new to wpf.
Can anyone help me out ?
I think that you need to do some change tracking on the Entities displayed in the grid. Whenever an Update is executed you check the state of the entities and only update those entities where it's needed. Basically you need to intercept at the level of Property Setters to keep track of changes in the entity. think about:
Using a base class that has some functionality for keeping track of the state of an entity. Very simple: a Boolean hasChanged or more "complex" an Enum with Added, Modified and Deleted or something.
Derive other entities from this base class
Work with public properties and private backing fields to intercept property modifications
When property modifications are executed store the information in a Boolean or Enum in the base class
When the update is initiated by the user loop through the entities presented in the Grid and pick those that have changes and send them to the database.
Some helpfull theory about this might be:
Change tracking on businees objects
Using Properties C# programming guide
ADO.NET Self Tracking Entities
I don't know from your question how tightly the coupling is between the user interface and the database (ADO.NET DataTables or so...). The idea presented above requires some "decoupling" of things. But, is a good basis for further functionalities in your application and can give you some ease of work, clear framework, improved maintenance and might increase performance.
I believe the easiest way to do this is to add a handler to controls, that are used to get user input, that will set some boolean property, e.d. RowWasEdited, to true. Then check this property on UPDATE button click event, do neccessary actions, and set it to false.
But I'm sure that there is something more elegant than this.
Ok, I have a couple of DataBindingSources pointing to context.[DbSet name].Local.ToBindingList()
there's a datagridview bound to such bindingsource, I have 2 columns set to 2 more databindingsources, thus when changing the values using the comboboxes the parent entity's navigation property changes. So far, so good, now when checking the State by:
if(context.Entry(databindingsource.Current).State == EntityState.Modified)
context.SaveChanges();
the State is not Modified but in fact Unchanged, I understand that was intended, and it's not a bug. What I do not understand is how am I suppose to save the changed Navigation property. What is the proper way to go about it? Am I suppose to catch OnChange event from the combobox check the content and set the entity to Modified manually? isn't there a more elegant way?
notes:
lazyloading is off
all entities are loaded prior binding everything to datagridview, comboboxes, and textboxes to their relative databindingsources
all changes are saved when DataBindingSource.CurrentItemChanged event fires
navigation properties are set to already retrieved entities, /ie entities with Unchanged state/
I'd like to post the code, but it's quite a mess, I believe explaining the problem should suffice. but if not I'm more than willing.
EDIT: the model is generated, DataBase first, database did not include any FK's so all associations are made after the entity generation
I have a Windows Form with some textboxes and a Save button. When the form loads the textboxes are populated with data from an entity in my model. When the user clicks on the save button the values in each textbox are written back to the entity and then SaveChanges is called to commit the data to the database.
What I'd like to know is what is the best way to check if the form contains changes? If it doesn't contain changes then I needn't call SaveChanges and I can save writing the record back to the database. If it does contain changes and the user hasn't clicked on the Save button I want to get the user's confirmation that the changes don't need to be saved.
I thought maybe I could just update the entity's fields and then check its State property before calling SaveChanges but this fails as updating any field, even with an identical value, causes the entity to be marked as modified.
So, my question is, what is the best way to check that changes have actually been made to the form before calling SaveChanges?
Thanks,
Matt
You can check the entity state. Just save the data from the textboxes to the entity ans see if the EntityState is EntityState.Unchanged.
Details here: http://msdn.microsoft.com/en-us/library/system.data.entitystate.aspx
Actually updating the field even with the same value as the previous one counts as a modified entity and in most cases this is the correct business rule.
What you could do is keep a copy of the original object that was used to fill the form fields and compare it with the current one using an equality comparer. It's not pretty but it gets the job done in particular cases where you cannot count on the object state manager's opinion of modified.
I am using a FormView with an ObjectDataSource. When the save button is clicked, I would like to modify the data bound object before it gets set to the ObjectDataSources Update method.
I tried the FormView's Updating event as well as the Object Data Source's Updating event but I can't figure out how to access the data bound object. FormView.DataItem is null in those events.
Or in other words, I would like to intercept and modify the DataItem before it gets passed to the ObjectDataSource UpdateMethod.
To give a little more detail on why I want to do this, there are some values on the form which can't be databound with the build in functionality. One of the controls is the checkbox list. I am using the DataBinding event to populate the checks, but now I also need a way to update my object to reflect the form values. There are also other controls with similar situations.
I know this is an old question, but I had the same problem, and found the answer I think Bob's looking for.
The solution is to use the ObjectDataSource Updating event on the Web Form. The Updating event includes the ObjectDataSourceMethodEventArgs object as a parameter. The ObjectDataSourceMethodEventArgs class includes a propery named "InputParameters", and you can use that to access the data object and modify the contents before the update occurs. You need to convert the InputParameters object to an OrderedDictionary type first (full namespace is System.Collections.Specialized.OrderedDictionary)
It looks something like this:
protected void myObjectDataSource_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
OrderedDictionary parameters = (OrderedDictionary)e.InputParameters;
MyDataObject updatedData = (MyDataObject)parameters[0];
DropDownList myDropDown = (DropDownList)FormView1.FindControl("myDropDown")
updatedData.SomeDataValue = myDropDown.SelectedValue;
}
Why don't you just write your own business object (aka ObjectDataSource), and wrap the original ObjectDataSource object? You can then intercept anything you want, and modify it enroute to the original ObjectDataSource object's Save method.
DataItem is only available when DataBinding.
Data is then bound to controls inside your FormView.
Use myFormView.FindControl(string id) to access bound values before Updating.
If two-way databinding won't work for you, you should instanciate your object, populate manually the properties and then update or commit the changes.
Since you are in the Updating event, FormView.DataItem is null because data binding has not yet occurred. You have to access the data via the form control containing your data of interest.
Try applying your data modification during the OnDataBinding event of the relevant control.