实体框架 - Web应用程序中的范围上下文

时间:2010-02-04 14:21:06

标签: .net asp.net entity-framework static scope

我在Web应用程序中为实体框架实现了一个简单的存储库模式。

我有几个存储库,它们都是一个基类,它在

中有一些常用的方法

基地看起来像这样

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

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

(RedirectsEntities是EF datacontext,或者其他任何名称)

我有一个RuleRepository和一个将其子类化的SiteRepository

但是,这在查找网站并使用该值保存到规则时会给我带来问题

错误是

“ADO.Net实体框架IEntityChangeTracker的多个实例无法引用实体对象”

大概是因为每个存储库都有不同的RedirectsEntities实例?

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

建议将datacontext移动到单独的类,将其保存在静态变量

e.g。

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的范围现在不正确。

有人可以对此发表评论吗?

1 个答案:

答案 0 :(得分:2)

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

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

<强>更新

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