|
You haven't been paying attention to what I've written. The reason you don't see this in applications is because if User B makes a change right before User A hits Undo, and WILL NOT KNOW about the change User B just committed, the undo is not going to undo what User A thought it should.
|
|
|
|
|
You are taking a case that has a low probability to happen.
"In a company 2 users works on the same record without knowing each other actions."
If you take this as probability , well the same problem will happen with the "Save" case.
User A and User B working on the same record trying to change the record with different values and after try to save. User A says to the boss " I change to this" , User B says "I change to this" .. So a chaos. Do you know any company works like this ?
Anyway even in your case the thing has sense.If the user B change right before the user A click Undo , The Undo process will return the state before the changes made by user B. User A can see what the undo has done and can press again undo to move up to another undo level. What's the problem here ? and just like in Word where you can see what actions you are Undo , here we can include in the Undo comments who has done the action that we are just trying to undo.
The idea of "Step by Step" Undo/Redo is to help people to return /forward to another step if they think that a mistake is done , just like in the Word where something that we have doesn't like to us we can go back step by step.
Instead of loosing time to this discussion , have someone an idea how can this be realized ?
Thank you !
|
|
|
|
|
satc wrote: You are taking a case that has a low probability to happen.
HA HA HA HA HA !!! You haven't been doing this for very long, have you? It WILL bite you in the ass! The second you say it's "rare" for that to happen, it'll happen within 10 minutes of you deploying your code to production.
Also, "rare" is not "cannot ever happen". It WILL happen and you WILL lose data when it does.
In my example, it doesn't have to be two people updating the same record within milliseconds of each other. Both users can retrieve the data, User B can update the record while User A stares at the ceiling tiles for 20 minutes before he decides to undo his last change. Guess what just happened! User A didn't retrieve the record again and didn't know that User B made a change!
How are you going to handle that? You WILL have to handle that situation.
satc wrote: Do you know any company works like this ?
Yes! The problem is called "concurrency" and people who write code have to deal with it every single day. Read up on it here[^]. There are various modes in which collisions like this can occur and various solutions to the problem, each with their pros and cons. Your job is to map your business rules to the situation and choose an appropriate method to deal with the problem, given the down side to the chosen solution.
In the website that I'm working on right now, we use two rules depending on the situation. We use either "last write wins" for data that isn't sensitive to changes of state and "optimistic concurrency" with the stuff that must maintain a consistent state across all involved fields. The later rule covering about 90% of our data.
satc wrote: just like in the Word
You absolutely can NOT compare Word to a multi-user database scenario. The problems are very different, with document editing being very easy to back out. The reason for this is because the code maintains the state of the data (Word document) completely on its own WITHOUT ANY OUTSIDE ALTERATIONS to the data being possible because only one person can edit the document at a time.
Any data in a database can be changed by anyone at any time. Your code on one workstation will not know a change was made by another workstation.
Database changes cannot be backed out so easily without very careful consideration of the different possibilities where changes are being made and accounting for every single one of them in your code. You immediately failed at this requirement the second you dismissed even one possibility as a "rare" occurrence.
Make no mistake. What you want to do is not simple. In fact, it's quite a large project in itself and many things to consider and design for, even the stuff that has only, say, a 1 millisecond window of opportunity to happen.
satc wrote: Instead of loosing time to this discussion , have someone an idea how can this be realized ?
You've already been told what you have to do and the possible pitfalls of various methods. The discussion of what you have to account for in your design and how to account for various things (given your business rules) will be a VERY long conversation and one that I doubt anyone is willing to take on in a forum environment.
|
|
|
|
|
When I say " Has a low probability to happen" ,I mean in the environment that I intend to apply it. I'm not talking in general. You don't know nothing about this , so take as TRUE that I'm saying.
Taking this supposition , can you give me an idea how to implement it or no ?
So can this be done or no , If no , ok end of the conversation.
|
|
|
|
|
satc wrote: I'm not talking in general
I'm not either.
|
|
|
|
|
Ok , then I can ensure that the case that you are talking about has almost 0 probability to happen in the environment that I'm going to use this program.
sorry , why you don't give any idea how can this be implemented ?
Because if you try to find a single justification to drop the idea , then I can tell you for example : " don't install a program in the Hard drive because the hard drive may be broken and you will loose your data ?" But how much probability has this event ?
|
|
|
|
|
satc wrote: I can ensure that the case that you are talking about has almost 0 probability to happen in the environment
May I point out that is it NOT ZERO. What are going to do when it does fail? How are you going to know?
Don't answer, I don't really care.
satc wrote: orry , why you don't give any idea how can this be implemented ?
First, because I don't have the time to write a series of articles on it.
Second, I/we know nothing about your application, it's design, your database design, your business rules, ... NOTHING.
If you want to define your problem as only one user ever uses the application at any one time, your problem becomes far far simpler. Just lookup the last transaction that was committed (and not undone) and create whatever transaction you want to reverse that.
|
|
|
|
|
Quote: First, because I don't have the time to write a series of articles on it.
Ah , finally a reason.
If I knew this from the beginning , I would not make so lot's of replies.
|
|
|
|
|
satc wrote: You don't know nothing about this Correct, thanks to the double negative.
You'll need to save the entire "state" and keep that in a stack. If you want that for tables, that means that all affected tables (and their content) become your state.
That would also only work if the state is accessed from a single location. If multiple people change state from different machines, then they will both have an incomplete list of changes, or they will affect each other.
Dave is right, the idea as a design is wrong.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Quote: Dave is right, the idea as a design is wrong.
Be more clear :
- Is wrong ?
- Is difficult to make ?
- Can't be done at all ?
- It's unusable even if can be realized ?
|
|
|
|
|
satc wrote: - Is wrong ? Yes. A undo/redo pattern applies to a current unit of work, ie, the 'dirty' document that the user is currently editing. Consider that record to be locked, and "stopping editing", moving to the next record becomes "saving a file".
satc wrote: - Is difficult to make ? Depends on how far you are willing to go. Do you want a set of tables that is edited by multiple users? Imagine user A undoing the changes of user B.
satc wrote: - Can't be done at all ? Sure it can be done; capture the entire state of your database as a single memento-item. If your database is 2 Gb, that means 2 Gb per undo/redo step
Do your users really need the functionality that bad? How would you have user A and B negotatiate about whom is right?
satc wrote: - It's unusable even if can be realized ? "Undo/redo" is aiming at the thing you are editing; it is limited to your Word/Excel/MSPaint/Whatever file/document, not to ALL documents on the network. That would create havoc, which does not count as a unique selling point
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Quote: Sure it can be done; capture the entire state of your database as a single memento-item. If your database is 2 Gb, that means 2 Gb per undo/redo step
This idea is an attempt to show the possible solution for this problem as bad as possible.
Why should I make an entire state of database for some hundreds records that are being changed ?
|
|
|
|
|
satc wrote: This idea is an attempt to show the possible solution for this problem So far I did not see one.
satc wrote: Why should I make an entire state of database for some hundreds records that are
being changed ? That is the easiest way to allow for unknown operations on the data whilst still being able to step "back" or "forward" to different states. If you have a better solution, please article it
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Never retreat! Advance! Advance! Advance!
I suspect you will need to devise a schema that allows you to keep all versions of the record so an older version can be re-activated when necessary, but it should be a very uncommon thing to do.
|
|
|
|
|
This Undo/Redo should function only when the database I "open" ( I mean when someone is using it). When the application is closed , all the data that take care of tis function should be deleted , and when the application is open again the story start from beginning.
( I say I want to mimic Word , so as long as the document is open , can be Undo/Redo step by step , when the document is closed , and re-opened , the olds Undo/Redo are lost.)
|
|
|
|
|
Hello !
I'm using entity framework.
I have a bindingsource bound to entity.
First when I fill the bindingsource I use this :
Bindingsource.Datasource=(From t in context.MyTable1 where t.vl>5 select t).Tolist
Now , let's suppose that for some of the bindingsource's items the vl's value is change to a value lower than 5.
How can I refresh my bindingsource in order to be correct with the condition specified on my first expression ( t.vl>5). In other words how to remove these items with vl<5 from the bindingsource ( but of course without deleting them from datasource , and without querying the database again).
Thank you !
|
|
|
|
|
The way you've bound your data, you have no choice but to execute the query again.
Instead of doing the filtering in the query (your where clause) let the query return all the records instead and let the UI control displaying your data handle the filtering, if it supports doing such a thing. You don't tell us anything about your display control so it's impossible to say.
|
|
|
|
|
I found the Bindingsource.RemoveAt or BindingSource.Removecurrent.
If I use these commands , the item is removed from bindingsource .
But my question is : If after I call context.savechanges , these items will be removed from database too ?
If no , then I've found the solution.
|
|
|
|
|
Your first post made it sound like you were trying to remove these items from the grid by filtering.
Now you're talking about updating the database, removing these items from the database?
Which is it?
In order for items to be deleted, you have to retrieve the items to be deleted from the database so they are being tracked by Entity Framework. You then, in Entity Frameworks object tracker, tag those objects to be deleted, one by one. Then you can call SaveChanges() and they will be deleted from the database.
You seriously need to pickup a book on Entity Framework and work through it. You're asking a bunch of questions that would have been answered already had you gone through the book.
|
|
|
|
|
My question is simple :
On a bindingsource , the methods Removeat and RemoveCurrent , only remove the items from the bindingsource , or mark them for deletions even from database ?
|
|
|
|
|
It affects only the data bound to the binding source. In your case, that would be a List<> of objects.
What you're doing will not affect the database at all.
|
|
|
|
|
The application has about 30 forms, some forms have menubars.
All forms and controls are singleton pattern.
I want to search all controls in the application to find a control instance with the specific string name, like, "MenuLogin".
I tried Me.Controls, but it only contain the controls of the current form.
Thanks
|
|
|
|
|
You'll have to keep a collection of all Forms in the application, then implement a method on each Form that searches that Form for the control you want.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Assuming the forms you want to search are currently open, then you can use the Application.OpenForms collection[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Some are opened, some are not
|
|
|
|