Это меня давно озадачило. Но я не эксперт. Это немного долго ...
У меня есть приложение WinForms с пользовательским интерфейсом в стиле Outlook. То есть на левой панели есть панель, которая позволяет вам выбрать «экран», который является элементом управления WinForms, скажем, экран клиента, а на правой панели появится список клиентов (т.е. контроль). Я называю это интерфейсом проводника. Двойной щелчок по записи вызовет немодальную запись о клиенте в дополнительном окне так же, как вы открываете электронное письмо в Outlook, мы называем это инспектором. Если дважды щелкнуть несколько записей, вы получите несколько инспекторов.
Все это делается с помощью привязки данных. Элемент управления BindingSource имеется в элементе управления списком клиентов, а другой - в инспекторе клиентов. Пользовательский элемент управления сообщает статический DataContext в своем событии загрузки и назначает результат простого запроса Linq-To-SQL свойству источника данных BindingControl. Если дважды щелкнуть список клиентов, событие ищет запись, преобразует ее в объект клиента Linq-To-SQL и передает ее в конструктор формы инспектора клиентов. Инспектор клиентов получает объект клиента и назначает ему свойство источника данных своего элемента управления BindingSource.
Поскольку элемент управления BindingSource поддерживает IBindingList, содержимое объекта клиента не изменяется до тех пор, пока не будет вызван EndEdit, в этом приложении при нажатии кнопки OK. Поскольку Linq to SQL реализует интерфейс INotifyPropertyChanged, список клиентов затем обновляется. Круто.
Однако проблема возникает, когда я хочу обновить содержимое списка клиентов, чтобы получать изменения, сделанные другими пользователями, что, как я хочу, происходит через регулярные промежутки времени, скажем, каждые 60 секунд. Если у меня есть таймер и я повторяю запрос к тому же текстовому тексту, никакие изменения не будут получены, потому что Linq to SQL не хочет отменять изменения, внесенные в данные, находящиеся под контролем текстового данных. Как ни странно, он выполняет запрос к БД, но отслеживание идентичности означает, что в список добавляются только новые объекты клиентов, возвращенные из БД. Если я создаю другой текстовый текст данных, то все открытые инспекторы клиентов больше не используют тот же текст данных, поэтому любые будущие изменения открытого инспектора клиентов не отражаются в списке клиентов.
В основном данные устарели, потому что я не использую шаблон единиц работы. Так что (если вы все еще со мной), вопросы.
1. Как, черт возьми, заставить эту модель работы работать в этой ситуации? В ASP.NET достаточно легко использовать текст данных с ограниченным объемом запроса, он недолговечный, но в WinForms?
2. Есть ли другие ORM, которые будут работать лучше в этом сценарии? NHibernate, EF, LLBLGEN и т. Д.
3. Как еще мне это сделать?
А также.
4. Если бы я мог заставить Linq to SQL работать таким образом, кто-нибудь реализовал IBindingList в частичных классах Linq to SQL, что позволило бы мне не использовать элементы управления IBindingSource. (Я не уверен, что должен заботиться об этом).
5. Если я смогу заставить Linq to SQL работать так, то есть ли способ использовать SQL-уведомления в SQL 2008, чтобы я мог получать уведомления об изменениях и запросах базового запроса, а не об опросе.
Спасибо!
P.S. Я знаю, что могу использовать
db.Refresh(System.Data.Linq.RefreshMode.KeepChanges, customers)
, но это вызывает выполнение запроса к БД для каждой записи клиента в списке.