2010-02-04 46 views
1

我已经在Web应用程序中为实体框架实现了一个简单的存储库模式。实体框架 - Web应用程序中的范围上下文

我有好几个版本库,所有的子类,在

底座看上去像这样

public class BaseRepository<TEntity> : IRepository<TEntity> 
{ 
    protected readonly RedirectsEntities Context; 

    public BaseRepository() 
    { 
     Context = new RedirectsEntities(); 
    } 

一些常用的方法(RedirectsEntities是EF的datacontext,或任何它被称为)基础

而且我有一个RuleRepository和一个SiteRepository,它将其子类化为

但是,这在查找网站并使用该值保存到规则

错误是

“ADO.Net实体框架的实体对象不能由IEntityChangeTracker的多个实例引用”

大概是因为每个仓库都有不同重定向实例的实例?

所以我发现这个问题: ADO.Net Entity Framework An entity object cannot be referenced by multiple instances of IEntityChangeTracker

这表明在DataContext移动到一个独立的类,在一个静态变量

例如保持它

public class DataContext 
{ 
    private static RedirectsEntities _dbEntities; 
    public static RedirectsEntities DbEntities 
    { 
     get 
     { 
      if (_dbEntities == null) 
      { 
       _dbEntities = new RedirectsEntities(); 
      } 
      return _dbEntities; 
     } 
     set { _dbEntities = value; } 
    } 
} 

,然后我的基地仓库的构造是这样的:

public BaseRepository() 
{ 
    Context = DataContext.DbEntities; 
} 

因此,这似乎已经解决了我的问题,但我担心的是RedirectsEntities的范围现在是不正确。

任何人都可以对此发表评论吗?

回答

2

在Web应用程序中,最常见的解决方案是根据http请求来确定上下文的范围。您在请求开始时初始化上下文,并在最后处理它。在请求期间,您可以将会话保存在会话状态中。

如果您使用控制反转(IoC)容器,您可以让容器负责在请求期间保存上下文并将其提供给您的存储库。

更新

如果你不使用IoC的我会创造在申请之初DataContext的,并把它的会话状态。然后,我将更改基本存储库的构造函数,以便将datacontext的实例作为参数。然后,每次创建存储库时,都会从会话中获取上下文并将其提供给存储库。在请求结束时,您从会话中获取上下文并处理它。这样,您的所有存储库将通过一个请求共享相同的上下文。

+0

感谢您的回答。我没有使用IoC容器。只是做穷人的依赖注射(哦,耻辱!) 所以在这种情况下,我会有DataContext作为存储库上的属性?在创建存储库实例之前新建一个DataContext?然后在存储库上设置datacontext属性? – ChrisCa 2010-02-04 15:14:32

+0

查看我更新的答案。 – 2010-02-04 15:30:32

+0

谢谢......这对于每个请求的范围确定都是非常好的技巧(尽管使用Lightspeed而不是EF) http://www.mindscape.co.nz/blog/index.php/2008/05/12/using-所述单元-的功每个请求图案在-ASPNET-MVC / – ChrisCa 2010-02-04 15:58:16