This one has been stumping me for a while. But I'm no expert. This is a bit long...
I have a WinForms app with an Outlook style UI. That it to say there is a bar on the left hand pane that allows you to select a 'screen' which is a WinForms control, say the customer screen, and on the right hand pane there will appear a list of customers (i.e. the customer control). I call this the explorer interface. Double clicking a record will bring up a non-modal customer record in an additional window in the same way you would open an email in Outlook, we call this the inspector. If you double click multiple records you get multiple inspectors.
The whole thing is done using databinding. There is a BindingSource control on the customer list control and there another on the customer inspector. The customer control news up a static DataContext in it's load event and assigns the result of a simple Linq-To-SQL query to the BindingControl datasource property. When the customer list is double clicked the event looks up the record, casts it to a Linq-To-SQL customer object, and supplies this to the constructor of the customer inspector form. The customer inspector gets the customer object and assigns the datasource property of it's BindingSource control to it.
Since the BindingSource control supports IBindingList the contents of the customer object are not modified until EndEdit is called, in this app when the OK button is clicked. Since Linq to SQL implements the INotifyPropertyChanged interface the customer list is then updated. Cool.
However the problem comes when I want to refresh the content of the customer list to pick up changes made by other users, which I want to happen at regular intervals, every 60 seconds say. If I have a timer and re-run the query on the same datacontext no changes are picked up, because Linq to SQL does not want to squash any changes that have been made to the data under control of the datacontext. Strangely it runs the query against the DB but the identity tracking means that only new customer objects returned from the DB are added to the list. If I new up another datacontext then any open customer inspectors are no longer using the same datacontext, so any future changes to the open customer inspector are not reflected in the customer list.
Basically the data is stale because I am not using the Unit of Work pattern. So (if you are still with me), the questions are.
1. How the hell do I make the unit of work pattern work in this situation? It's easy enough is ASP.NET to use a request scoped datacontext, it's short lived, but in WinForms?
2. Are there any other ORMs that would work better in this scenario? NHibernate, EF, LLBLGEN etc.
3. How else should I go about it?
And also.
4. If I can make Linq to SQL work like this has anyone implemented IBindingList in the Linq to SQL partial classes which would avoid me having to use IBindingSource controls. (I'm not sure I should care about this).
5. If I can make Linq to SQL work like this is there any way of using SQL Notifications in SQL 2008 so that I can be notified when the underlying query results changes and requery then, rather than polling.
Thanks!
P.S. I am aware that I can use
db.Refresh(System.Data.Linq.RefreshMode.KeepChanges, customers)
but this causes a query to be run against the DB for each customer's record in the list.