2009-12-22 3 views
5

Мы пишем приложение WPF с использованием инфраструктуры Entity (Silverlight с услугами RIA, если быть точным). Мы используем общий объект ObjectContext через приложение, чтобы мы могли использовать данные для обмена данными через модули.Entity Framework ObjectContext в приложении Windows/WPF/Silverlight

Проблема заключается в том, что если пользователь во время своей работы открывает, скажем, исторические продажи, он загружается в ObjectContext и остается там до конца приложения. Поэтому следует использовать еще один шаблон.

Я знаю, что ObjectContexts следует использовать как единую единицу работы. Но тогда, как вы позволяете другим частям приложения знать, что что-то изменилось, и они должны перезагрузить свои данные?

Редактировать: Хорошо, EventAggregator, но тогда это приведет к тому, что все остальные части будут перезагружать (возможно, большую часть дубликатов) данных. Также возможно, что для всех типов групп entites потребуется много событий.

Как вы решаете эти проблемы? Мое текущее решение - это своего рода компромисс - используйте общий ObjectContext для основных данных, используемых целым применением, чтобы их можно было совместно использовать и обновлять автоматически. А для большого объема данных используйте новый отдельный ObjectContext. Любые лучшие идеи?

Есть ли способ «освободить» объекты из своего DataContext, чтобы сборщик мусора мог выполнять свою работу и освобождать память?

ответ

2

Подождите, это WPF или Silverlight? В этом случае они очень разные, и мой ответ будет другим.

WPF Решение

В WPF я хотел бы создать единый ObjectContext по форме. Таким образом, контекст будет продолжаться до тех пор, пока сама форма. Затем вы должны внедрить систему событий, чтобы при сохранении изменений в сущности вы могли предупредить другие формы, которые им могут понадобиться для обновления своих данных (например, INotifyPropertyChanged). Oren Eini wrote a pretty good article on this architecture using NHibernate in MSDN magazine. Вы должны иметь возможность получить концепцию архитектуры из своей статьи.

Silverlight Решение

Теперь Silverlight отличается. Silverlight по сути только позволяет вам иметь одну форму в вашем приложении. Да, есть некоторые трюки, которые вы можете сделать, чтобы ориентировать корневую визуальную форму формы на разные «страницы», но она остается только одной формой, и пользователь не может открыть несколько окон в одном Silverlight RIA. Из-за этого, Я бы сделал один. Net RIA Services ObjectContext для экземпляра Silverlight RIA. Помните, что RIA Services не является фактическим подключением к вашей базе данных, это всего лишь объект отслеживания кэширования и изменения, связанный с веб-службой. Таким образом, вполне приемлемо оставлять этот объект в ожидании в течение более длительных периодов времени, поскольку он не связывает никаких ресурсов сервера. Если ваш Silverlight RIA открывает несколько окон браузера или имеет более одного объекта Silverlight, тогда у вас должен быть один объект ObjectContext для экземпляра Silverlight.

На сервере в веб-службе используется объект ObjectContext Entity Framework и он должен работать только в течение одного запроса. Чем больше лиц без гражданства вы можете сделать свои услуги, тем более масштабируемыми и эффективными они будут. Вы хотите открыть свой EF ObjectContext, использовать его и как можно скорее закрыть его.


EDIT:

Если все, что вы желаете, чтобы сделать, это отделить объект от контекста объекта, то вы можете просто использовать метод context.Detach(entity). Вы можете найти example of how to do this on MSDN.

+0

С помощью этого приложения мы говорим о Silverlight. Используя Prism/Caliburn, я считаю, что не проблема иметь один ObjectContext для представления (модуль?). Опять же, проблема в том, что, если для клиента загружено много данных? Насколько я знаю, лучшим решением было бы создать общий объект ObjectContext для базовых объектов, которые используются во всем приложении, чтобы они автоматически синхронизировались, и отдельные объекты ObjectContext для загрузки большого количества данных, например. некоторые исторические отчеты. – gius

+0

Я бы не стал посылать клиенту действительно большие блоки данных. Вместо этого я буду фильтровать на сервере и возвращать только те результаты, которые клиент хочет увидеть в этот момент. Люди не могут читать 100 000 записей, поэтому не отправляйте их людям. Вместо этого пусть проблема будет искать/фильтровать и отправлять результаты только клиенту. Если вы создаете отчеты, создайте сводные сводные данные на сервере. Например, было бы лучше рассчитать ежемесячный объем продаж на сервере и отправить единый номер клиенту, а не 5000 записей о продажах. –

+0

Это правда, но если пользователь видит в любое время в течение жизни приложения, скажем, страницы 1, 10, 20, эти данные все равно будут в памяти. С другой стороны, использование отдельного объекта ObjectContext и пейджинга данных может решить проблему с большими объемами данных в памяти. – gius

1

Вы можете использовать шаблон репозитория. Дополнительный слой абстракции между UI и DAL.

Сделать сбор данных в хранилище статическим и наблюдаемым. Затем, когда репозиторий обновляет любой из них, уровень пользовательского интерфейса должен догнать. У меня есть идея.

+0

Это не решает мою проблему - коллекции будут оставаться на клиенте, так что если есть, например, 1 ГБ данных в базе данных, рано или поздно, он также будет загружен на клиенте. С другой стороны, это может показать возможное решение. Спасибо за идею! – gius

0

Использовать ObservableCollections в ObjectContext. Используйте событие, которое запускается в NotifyPropertyChange. Используйте шаблон публикации/подписки между моделями просмотра, чтобы сообщить им об изменении и использовать его для обновления других представлений.

+1

Все коллекции, созданные EF, являются ObservableCollection, а объекты используют NotifyPropertyChanged. Проблема в том, что я не могу использовать только ObjectContext в течение всего жизненного цикла приложения, потому что тогда данные не будут освобождены из памяти после их загрузки в приложение. С другой стороны, использование отдельного объекта ObjectContext для каждого отдельного действия вызовет проблемы с обновлением данных - одни и те же данные будут загружаться несколько раз из многих мест, а синхронизация будет означать пользовательские события для каждого типа данных. Главный вопрос: есть ли какая-либо структура/шаблон для этой проблемы. – gius

0

В нашем случае мы решили внедрить фабричный шаблон и создать экземпляр нового контекста объекта, когда нам это нужно (иногда он не сопоставляет один к одному с виртуальной машиной).

Agreat статья об объекте времени контекст жизни: http://www.silverlightshow.net/items/Silverlight-WCF-RIA-Services-strategies-for-handling-your-Domain-Context-part-one.aspx

Смежные вопросы