У меня есть служба Windows (или Windows Forms) , и по истечении таймера моя служба выполняет некоторые задачи.

Я не хочу использовать только один контекст Entity Framework , пока работает мое приложение.

Я видел фабрику сеансов в образцах NHibernate . Есть ли что-нибудь подобное для EF ?

Вот как я использую EF + StructureMap в своих приложениях ASP.NET или MVC :

Запуск приложения:

ObjectFactory.Configure(Function(config) config.For(Of IUnitOfWork).HybridHttpOrThreadLocalScoped.Use(Of UnitOfWork)())

Завершить запрос:

ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()

Мой UnitOfWork запускается по веб-запросу и удаляется после завершения запроса.

В моем сценарии приложения Win , UoW должен запускаться по истечении таймера и удаляться после завершения моей работы, а я не хочу обрабатывать это сам. < / сильный>

Как добиться этого в приложении Windows Form?

Если я зарегистрирую свой UoW, используя: HybridHttprThreadLocalScoped Есть только один UoW на поток , и если я утилизирую его, он исчез .

< EM> EDIT :

У меня есть репозитории + службы в dll , и я хочу использовать их как в веб-приложениях, так и в приложениях для выигрыша , поэтому я использовал HybridHttpOrThreadLocalScoped.

Обновление 2:

Вот мой репозиторий :

Public Class ProductRepository

    Private ReadOnly _databaseFactory As DataAccess.IDatabaseFactory

    Public Sub New(ByVal databaseFactory As DataAccess.IDatabaseFactory)
        _databaseFactory = databaseFactory
    End Sub

    Public Function GetById(ByVal id As Integer) As Product
        Return (From item In _databaseFactory.GetDataContext.Products Where item.ProductId = id).FirstOrDefault
    End Function

End Class

А вот и моя Служба :

Public Class ProductService

    Private ReadOnly _Repository As ProductRepository

    Public Sub New(ByVal repository As ProductRepository)
        _Repository = repository
    End Sub

    Public Function GetById(ByVal id As Integer) As Product
        Return _Repository.GetById(id)
    End Function

End Class

И я использую StructureMap . StructureMap использует мои DatabaseFactory и время жизни UoW в веб-сценариях . Но я понятия не имею, что делать в выигрышных приложениях . Я могу управлять временем жизни UoW сам , но я ищу способ, чтобы StructureMap справился с этим за меня , поскольку он обрабатывает время жизни в веб-приложениях.

3
Afshin Gh 2 Май 2011 в 21:35
Афшин У меня такая же проблема, как у вас. Не могли бы вы поделиться своим окончательным решением?
 – 
Shahin
8 Апр 2013 в 18:36
@shaahin: мое текущее решение не идеально. Я постараюсь добавить его в этот пост как можно скорее. В веб-приложениях начало и конец запроса сигнализируются фреймворком, но в приложениях для Windows это не так, поэтому я делаю это вручную и как бы имитирую. например: в методе обработчика нажатия какой-либо кнопки (в приложениях win) я сигнализирую о начале и завершении запроса к моей собственной инфраструктуре.
 – 
Afshin Gh
9 Апр 2013 в 06:41

3 ответа

Лучший ответ

ASP.Net предоставляет инфраструктуру (по сути, один httpcontext на запрос) для управления временем жизни вашего объектного контекста. В winforms (очевидно) нет ничего похожего. Таким образом, способ управления контекстом EF будет сильно зависеть от архитектуры вашего приложения.

Например, если у вас есть приложение в стиле MVP или MVVM, вы можете связать время жизни вашего контекста со временем жизни Presenter или ViewModel. Или вы можете использовать абстрактную концепцию «пользовательской истории» и связать с ней время жизни вашего объектного контекста. Это действительно зависит от обстоятельств.

Для вдохновения просмотрите эту статью Айенде (она об управлении сеансами с NHibernate, но концепции те же. Подумайте NHibernate Session == Entity Framework ObjectContext)

4
jeroenh 3 Май 2011 в 16:58
Спасибо за ответ. Я прочитал упомянутую вами статью. Проблема заключается в следующем: в веб-приложениях запускается структурная карта и удаляет мой UoW для каждого сеанса. В приложении win карта структуры запускает один UoW для каждого потока, и если я управляю временем его жизни и удаляю его после удаления моего докладчика, Uow уходит, но поток все еще жив! Я думаю, мне следует больше изучить карту структуры, и, как вы сказали, это сильно зависит от архитектуры моего приложения.
 – 
Afshin Gh
3 Май 2011 в 19:41
Gh Я не думаю, что время жизни uow должно управляться контейнером IoC, оно должно быть явным (по крайней мере, в настольном приложении
 – 
jeroenh
11 Май 2011 в 21:56
Да. Я не мог найти лучшего подхода. Похоже, я должен сам управлять этим в выигрышных приложениях. Подожду еще немного других ответов. (И проголосовали за ваш ответ.)
 – 
Afshin Gh
12 Май 2011 в 00:12

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

Следовательно, в настольном приложении вам нужно будет реализовать управление сеансом вручную (обычно для каждой бизнес-операции).

ОБНОВЛЕНИЕ: этот пост имеет соответствующий код на сеансах

1
oleksii 11 Май 2011 в 21:52
Я полностью осведомлен о различиях между веб-приложениями и приложениями для выигрыша. В NHibernate у вас есть Session Factory. Что равняется этому в EF?
 – 
Afshin Gh
11 Май 2011 в 02:48
Гх извините за бессмысленный ответ. Может, тогда ты сможешь увидеть этот пост? peplowdown.wordpress.com/2010 / 07/05 /… Этот парень создает фабрику сессий и сессии с EF.
 – 
oleksii
11 Май 2011 в 14:36
Статья, которую вы связали, не совсем то, что я искал, но она полезна. Я ценю вашу помощь, я проголосовал за ваш ответ, и я буду ждать, пока другие проголосуют и ответят.
 – 
Afshin Gh
11 Май 2011 в 21:00

Entity Framework предоставляет вам «Контекст», который является своего рода сеансом с областью действия единицы работы внутри себя, все операции, выполняемые для одного контекста, остаются в области действия контекста. И Entity Framework уже реализует шаблон Unit Of Work. EF также реализует карту удостоверений, поэтому для одного первичного ключа вы найдете только один объект, на который есть ссылка везде в свойстве навигации.

Для настольного приложения вам нужно поддерживать только один контекст, который будет областью всех операций, и он хранит все операции в правильном состоянии до тех пор, пока вы не вызовете SaveChanges.

Для веб-приложения вы можете поместить свой контекст в сеанс ASP.NET, что может увеличить нагрузку на сервер, но может позволить вам хранить изменения дольше, чем на одной странице.

Я не хочу использовать только один контекст Entity Framework, пока работает мое приложение.

Что не так с одним контекстом, пока приложение работает? Напротив, это правильный способ сделать это. Сохранение одного контекста живым не означает, что вы поддерживаете соединение с базой данных. Соединения с базой данных открываются и закрываются только при запросе и сохранении изменений.

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

1
Akash Kava 17 Май 2011 в 11:18
Мне не нравится поддерживать мой контекст, пока работает мое приложение win. запускать свой UoW, когда он мне нужен, и закрывать его после того, как работа сделана, мне кажется лучше. но вы совершенно правы и ваш ответ полезен. проголосовал за это.
 – 
Afshin Gh
17 Май 2011 в 22:56
ObjectContext не предназначен для долгоживущего объекта. Не рекомендуется поддерживать его в рабочем состоянии (например, потому что все, что вы запрашиваете, остается в кэше, поэтому чем дольше он остается в живых, вероятность того, что вы сможете просмотреть устаревшие данные в многопользовательских средах), возрастет.
 – 
jeroenh
18 Май 2011 в 00:39
@jeroenh, если вы читаете мой ответ, я не предлагаю никому сохранять ObjectContext в течение более длительного времени в многопользовательской среде, для одного пользователя это лучший и наиболее предпочтительный способ сохранить его долгое время, потому что вы будете хранить свои объекты в память в любом случае, чтобы отобразить, просмотреть и отредактировать.
 – 
Akash Kava
18 Май 2011 в 13:04