Cancelling and discard changes in Entity Framework and WPF - wpf

I am developing a system where the user have forms to fill and this info is stored in a database. In one of the screens I have the following flow:
Inside a project he can add multiple orders.
Each added order opens a configuration screen which internal information of the order can be set. Also it is possible to add items to the order.
Each added item opens a configuration screen that allows user to set internal informations.
To sum up, the flow is Project -> Order -> Item, where "A -> B" means A contains 0, 1 or more Bs.
This project is being developed using WPF with Entity Framework to manage the database access. I am binding entities from Entity database mapping directly into the screens. This way we have some "advantages" with WPF, as not null fields are painted red, for example. Moreover, the code is much simpler. The entities are only updated (or added) to the database when the project is saved. Therefore, items can be edited, then orders can be edited and they are only saved when the project is saved, since they are dependent of the project ID to be saved.
However, using mapped entities directly has a huge problem: let's say the user edits an Item inside an Order. Then, he edits it again, but this time, instead of pressing "OK", the user presses "Cancel". The changes must be reverted. However, the previous state was lost, since it was not updated in the database and were changed because of WPF binding.
What is the best approach to prevent this problem? I don't know if creating clones work well in Entity Framework. And creating variables that only transfer their values to the object when the confirm command is clicked would be against the MVVM pattern, and would make me lose the "advantages" I have already talked about.
Please help me!
Thanks!

Related

WPF MVVM architecture, what is the best practice communicate between model and viewmodel

We are developing a TODO list kind of application in WPF
1)when user logs in we load list of workitem for the user(only basic details)
2)when user opens particular workitem we load all its information from service
3)we use signalr to add new workitem to the user when he is working on the system (singalr will
send the workitemid, and based on it we will fetch basic detail and add it to the workitem list)
Whenever user edits the workitem, if he changes anything in the workitem information, we should move it to UnSaved List, and if he reverts it we need to move the workitem to Opened List
1)when user enters something in screen it directly alters model (letsay workitem model has user model and user model has firstname, this firstname is bound to the textbox), how to communicate this change
to the viewmodel, so that viewmodel will move this workitem to unsaved list.
To find out a workitem is dirty or not, we are keeping Unchanged workitem details inside each workitem, so whenever user changes something in screen we make comparision with this unchanged workitem and move it to unsave or opened list.
2)Is it right approach to have Unchanged workitem inside each workitem, are there any best approach or pattern available?
3)how to differentiate between user changing some value of workitem and system changing values of workitem
let say A and B user sees the same workitem in edit mode, User A edits some value in workitem and
saves it, now user B will receive this information through signalr notification, and we will make a call to service based on this workitemid and will populate the changes in B's screen. Now we should not move the workitem to unsaved list, because changes are done by system.
4)Moreover we will recieve lot of signalr notification related to multiple workitems, we don't
want to make multiple service call as and when signalr notification comes, but whenever user clicks on workitem we would like to see the changes done in that workitem from other user. What is the efficient way of doing this. (We don't want notification to contain all the information, we kept only the Id and type of the notification, so that signalr will be as lean as possible)
5)how to compensate for singalr notification failiures, (we could make some kind of timer which will periodically poll list of notifications based on the last arrived notificationid).
Is this a good approach or any pattern exist for this kind of problems.
I am not quite sure if I understand your questions.
So conceptionaly I think you are thinking about a real-time collaboration sort of software.
There are patterns and algorithm how this is solved in a distributed fashion. You should look for the papers of the google wave protocol (the foundation of the real time editing feature of the google docs tools) http://www.waveprotocol.org/whitepapers. Or research for Operational Transformation: https://operational-transformation.github.io/.
The good think is that there are already libraries out there which handle protocols like this and adapt or extend these concepts.
But finding the right library for handling realtime callobrative work over signalrs whould be a huge win. Don't know if there is also a library that builds on top of signalrs - might be worth a google or bing session.
But I think before you talk about technical details as c# or mvvm it would be a good start to understand the background of real time collaborative communication in distributed systems.
Like I said I hope I got your question correct and since you did not post any source code there is no chance to be more precise...
HTH and leads you into the right direction.

Multi-user support with nhibernate winforms application

I’m working on a multi-user winforms application (MDI). Our application uses NHibernate and one session per instance.
The problem is if an user makes modification, for example a user adds an item to a list, another user doesn’t see this modification immediately. How do I get around this, what is the recommended approach? Should I be using One-session-per-form or something else?
Every application needs to define it's own unit of work. For your use case, if you are wanting the database to update every time a user adds an item to a list, then that should be your unit of work.
So to answer your question for your unique use case, I would create a new NHibernate session, persist the users changes, and dispose of the session every time a user adds an item to the list.
FYI: You should not feel that there is anything wrong with creating a session per user action if that is indeed the behavior your application desires. Typically in a WinForms application, most people do use a Session-per-Form pattern but then again, that is because most WinForms applications fall into the model of having a form that the user needs to complete before proceeding to the next form. In those cases, you would only want to persist/save the user's changes when they submit the form. But if you application does not fall into that model, then your definition of a unit of work ( session life-cycle ) could be completely different.

Django multiple foreign keys or one enough?

I'm fairly new to Django having up to this point used to it display data from other sources.
I'm embarking on a new project and have a query about the way Django handles model relations (did some searching couldn't find much for this specific instance) and am wondering the most efficient way of accomplishing it.
I have 3 Models, User(obviously :S), Project and Report. Now a report is part of a project and done by a user but project is also 'owned' by a user. In that other users cannot see either the reports/projects of another user. Do i need two foreign keys for Report or just one (e.g User creates projectA and Report1, since Report1 is linked to Project it is also linked to User) ie:
Class Report(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
or
Class Report(models.Model):
project = models.ForeignKey(Project)
If a report is only associated with a user through the project (this means specifically that it makes no sense to have a report with a different user than its project) then the second one is better. You will always be able to access the user by (report object).project.user, or in search queries as 'project__user'. If you use the first one you risk getting the user data for the report and the project out of sync, which would not make sense for your app.

What is the best way to identify updated items in an in memory list?

I'm using Siaqodb for my client side database engine in a Sync Framework silverlight project. I've switched to siaqodb because microsofts client side solution loads the entire database into memory at once and, as such, has a hard time handling large data.
I've bound a list of SiaqodbOfflineEntity objects to a silverlight datagrid in order to create an editable datagrid. Unlike microsofts solution, you can't bind the database entries directly to the datagrid. You have to query the database and bind a list of in memory objects to the datagrid. This causes a problem in that the database isn't immediatly updated when the datagrid cell is changed. I'm trying to find the best way to handle updates to the database after a change in the cell. I can't just update each item to the database because the siaqodb engine will mark the item as dirty even if no change was made to the object. This will cause conflicts when trying to sync. holding a cached version of the original list and then comparing each property of each object to find which ones have changed seems like it would work, but seems to be a bit cumbersome. I've also tried looking at some of the datagrids events but RowEditEnded doesn't appear to fire when a cell is edited and CurrentCellChanged seems to fire whenever I switch rows (odd).
There's got to be a better solution to this. Anyone have any ideas?
So I've gotten this to work by changing my offline entity classes to implement iNotifyPropertyChange and I think this is a reasonable solution. I set the PropertyChanged event to a function that saves the object to the database. There is a VS package called notifypropertyweaver that will inject this code at compile time, reducing the amount of work needed to be done on auto-generated entity code.

Real time database query

We have a windows program written in vbasic(i think) and we are re-writing the same program in c#. In the old program there is a grid. When we click any cell and as soon as edit the cell content the data in database is changing. In our new program we couldn't find the way of doing that. So we added some buttons for database actions like update selected cell.
What is the best way to do that?
You can do this in c# too.Use a datagridview and to bind with the database so that change in the grid effect database see here
Out of seeing dozens of legacy ODBC frontends put together in Access I would strongly advice not to commit changes in the database at real time. Instead try to create a lightweight process that helps the users to keep their data's quality high.
If you want this kind of functionality you could have the real time changes saved in a different schema, a set of different tables or with a flag that tells that these rows are unverified edits by the user X.
Rasel already gave you a pointer how to do the functionality in C#.

Resources