实体框架+生命周期+结构映射+工作单元+ Windows窗体

本文关键字:工作 单元 Windows 映射 窗体 结构 框架 生命 周期 实体 | 更新日期: 2023-09-27 17:54:49

我有一个windows服务(或windows窗体),当计时器经过时,我的服务完成一些任务。

我不想只使用一个实体框架上下文,只要我的应用程序在运行。

我在NHibernate示例中看到了会话工厂。对于EF有类似的东西吗?

下面是我如何在我的ASP中使用EF + StructureMap。. NET或MVC apps:

应用程序开始:

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

请求:

ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()

My UnitOfWork是根据web请求开始的,在请求结束后被处置

在我的Win App场景中,UoW应该在计时器经过并在我的工作完成后被处理时启动,我不想自己处理它

我怎么能在一个windows窗体应用程序实现这样的东西?

如果我使用:HybridHttprThreadLocalScoped注册我的UoW,每个线程

只有一个UoW,如果我处理它,它消失了

编辑:

我有我的存储库+服务dll,我想在 web或win应用程序中使用它们,因为我使用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在web场景中使用我的DatabaseFactoryUoW寿命。但是我不知道在win apps中该怎么做。我可以自己管理UoW 的生命周期,但我正在寻找一种方法,所以StructureMap将为我处理,因为它处理web应用程序的生命周期。

实体框架+生命周期+结构映射+工作单元+ Windows窗体

Net提供了管理objectcontext生命周期的基础设施(基本上每个请求一个httpcontext)。在winforms中(显然)没有类似的东西。因此,管理EF上下文的方式将高度依赖于应用程序的体系结构。

例如,如果你有一个MVP或mvvm风格的应用程序,你可以将你的上下文的生命周期与Presenter或ViewModel的生命周期相耦合。或者你可以使用"用户故事"的抽象概念,并将对象上下文的生命周期与之耦合。这得看情况。

要获得灵感,请参阅Ayende的这篇文章(它是关于使用NHibernate进行会话管理的,但概念是相同的)。考虑NHibernate会话==实体框架ObjectContext)

Web应用程序是无状态的,而桌面应用程序是有状态的。在web中,对象通常是按请求创建的,并以同样的方式处理。这样做的原因有很多(比如处理多个请求和有限的内存量等),这就是为什么要为此准备好所有基础设施的原因。在桌面,你可以把所有的东西都存储在内存中。

因此,在桌面应用程序中,您需要手动实现会话管理(通常是每个业务事务)。

更新:这篇文章有关于会话的相关代码

实体框架给你"上下文",这是一种会话,它本身具有工作单元的范围,所有为一个上下文完成的操作都保留在上下文的范围内。而实体框架已经实现了工作单元模式。EF也实现了身份映射,所以对于一个主键,你会发现在导航属性中只有一个对象被引用。

对于桌面应用程序,你只需要维护一个上下文,这将是所有操作的范围,它将所有操作存储在正确的状态,直到你调用SaveChanges。

对于Web应用程序,您可以将上下文放在ASP的Session中。. NET,这可能会增加服务器的负载,但它可能允许您存储更改更长的持续时间,而不仅仅是一个页面。

我不想只用一个实体框架上下文,只要我的应用程序在运行。

只要应用程序正在运行,一个上下文有什么问题?相反,这是正确的做法。保持一个上下文活动并不意味着保持与数据库的连接活动。只有在查询和保存更改时才能打开和关闭数据库连接。

如果你的应用有点失衡并导致内存问题,最好的方法是分配新的上下文并刷新你的UI,它会把所有旧的上下文和它的对象放入垃圾收集器,你的新上下文将为你提供更少的内存