C# 实体框架&x2B;寿命+;结构图+;工作单位+;Windows窗体?

C# 实体框架&x2B;寿命+;结构图+;工作单位+;Windows窗体?,c#,.net,entity-framework,structuremap,unit-of-work,C#,.net,Entity Framework,Structuremap,Unit Of Work,我有一个windows服务(或一个windows窗体)当计时器用完时,我的服务会完成一些任务 只要我的应用还在运行,我不想只使用一个实体框架上下文 我在NHibernate中看到了会话工厂。EF有类似的东西吗 以下是我如何在我的ASP.NET或MVC应用程序中使用EF+StructureMap: 申请开始: 结束请求: 我的UnitOfWork是根据每个web请求启动的,并且在请求结束后被处理 在我的Win应用程序场景中,UoW应该在计时器过期时启动,并在我的工作完成后处理,我不想自己处理它。

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

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

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

以下是我如何在我的ASP.NET或MVC应用程序中使用EF+StructureMap

申请开始:

结束请求:

我的UnitOfWork是根据每个web请求启动的,并且在请求结束后被处理

在我的Win应用程序场景中,UoW应该在计时器过期时启动,并在我的工作完成后处理,我不想自己处理它。

如何在windows窗体应用程序中实现类似的功能

如果我使用:
HybridHttpThreadLocalScope
注册我的UoW,那么每个线程只有一个UoW
,如果我处理它,它就消失了

编辑:

我在dll中拥有存储库+服务,我想在web或win应用程序中使用它们,因此我使用了
HybridHttpOrthReadLocalScope

更新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
这是我的服务

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场景中使用我的数据库工厂的carUoW生命周期的car。但我不知道在赢取应用程序中要做什么。我可以自己管理UoW的生存期,但我正在寻找一种方法,让StructureMap像处理web应用程序中的生存期一样为我处理它。

ASP.Net提供了管理objectcontext生存期的基础结构(基本上每个请求一个httpcontext)。winforms中(显然)没有类似的东西。因此,管理EF上下文的方式在很大程度上取决于应用程序的体系结构

例如,如果您有一个MVP或MVVM样式的应用程序,那么您可以将上下文的生存期与演示者或ViewModel的生存期耦合。或者,您可以选择“用户故事”的抽象概念,并将对象上下文的生命周期与之结合起来。这要看情况而定


灵感来源,(这是关于NHibernate的会话管理,但概念是相同的。想想NHibernate会话==实体框架ObjectContext)

Web应用程序是无状态的,而桌面应用程序是有状态的。在web中,对象通常是根据请求创建的,并以同样的方式进行处理。这样做有很多原因(比如处理多个请求和有限的内存量等),这就是为什么您已经准备好了所有的基础设施。在桌面中,您可以将所有内容存储在内存中

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


更新:实体框架为您提供了“上下文”,这是一种会话,它本身具有工作单元的范围,为一个上下文执行的所有操作都保留在上下文的范围内。实体框架已经实现了工作单元模式。EF还实现了标识映射,所以对于一个主键,您将在导航属性中的任何位置都只能找到一个引用的对象

对于桌面应用程序,您只需维护一个上下文,即所有操作的作用域,它将所有操作存储在正确的状态,直到您调用SaveChanges

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

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

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


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

谢谢你的回复。我看过你提到的那篇文章。问题是:在web应用程序中,structuremap为每个会话启动并处理我的UoW。在win应用程序中,结构图为每个线程启动一个UoW,如果我管理它的生命周期,并在我的演示者被释放后将其释放,UoW将消失,但线程仍处于活动状态!我认为我应该更深入地研究structuremap,正如你所说,它在很大程度上取决于我的应用程序的架构。@Afshin Gh我认为uow生命周期不应该由IoC容器管理,它应该是明确的(至少在桌面应用程序中是的。我找不到更好的方法。看来我必须在win应用程序中自己管理它。我会再等一会儿,等待其他答案。(并投票支持你的答案。)我完全了解web和win应用程序之间的差异。在NHibernate中,你有会话工厂。EF中的会话工厂与之相等吗?@Afshin Gh很抱歉给出了一个毫无意义的答案。也许你可以看到这篇文章。这家伙用EF创建会话工厂和会话。你链接的文章,不完全是我想要的,但它很有用。我感谢您的帮助,我投票支持您的答案,我将等待其他人投票并回答。我不喜欢在我的win应用程序运行期间保持我的上下文处于活动状态。启动我的UoW wh