Singleton中的实体框架上下文

时间:2011-09-21 11:49:08

标签: c# .net entity-framework entity-framework-4 ninject

我正在构建一个在单例模式中使用EF的上下文的应用程序,就像NHibernate使用Session一样:

public class DbContextFactory
{
    private static volatile DbContextFactory _dbContextFactory;
    private static readonly object SyncRoot = new Object();
    public DbContext Context;

    public static DbContextFactory Instance
    {
        get
        {
            if (_dbContextFactory == null)
            {
                lock (SyncRoot)
                {
                    if (_dbContextFactory == null)
                        _dbContextFactory = new DbContextFactory();
                }
            }
            return _dbContextFactory;
        }
    }

    public DbContext GetOrCreateContext()
    {
        if (this.Context == null)
            this.Context = new DbContext(ConfigurationManager.AppSettings["DefaultConnectionString"]);

        return Context;
    }
}

我正在使用Ninject来注入上下文:

public class DbContextModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDbContext>().ToConstant(DbContextFactory.Instance.GetOrCreateContext());
    }
}

我正在读这种方法,有些人说这是不好的做法,我会遇到问题。

有人通过EF了解这一点可以向我解释一下吗?

4 个答案:

答案 0 :(得分:3)

NHibernate不会将Session用作单例...这种情况仅在极少数情况下意味着您的应用程序是非常短的代表单个事务/工作单元的批处理。

Here are described reasons为什么你不应该使用共享/长期生活环境。如果多线程或服务器应用程序为多个客户端提供服务,则不得使用共享上下文。

答案 1 :(得分:0)

一个好的实践是每单位工作使用一个datacontext 要获得有关EF工作单元的更多信息,请阅读http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx

当共享相同的datacontext时,您可能会节省几十毫秒。微观优化这个词让人想起 - 在这种情况下,您可能不应该使用实体框架。

拥有一个永不关闭的DataContext允许您随时延迟加载。您可能已经离开了您的服务,现在已经在您的控制器中,或者更糟糕的是,您的视图。从View访问数据库是在询问性能问题,因为我确信您没有故意这样做。这很可能是因为您忘记了加载填充视图所需的所有数据。

答案 2 :(得分:0)

你读过这篇文章。 为什么你不应该在Entity Framework中使用单例DataContexts? http://www.britishdeveloper.co.uk/2011/03/dont-use-singleton-datacontexts-entity.html

答案 3 :(得分:0)

public class Dock
{
    // Statik field
    private static Dock _dock;
    // lock object
    private static object lockObject = new object();

    // We prevent the constructive method from being modeled with new by 
    //making it secret.
    private Dock()
    {

    }
    // Class in Instance
    public static Dock Instance()
    {   
        if (_dock == null)
        {
            lock (lockObject)
            {
                if (_dock == null)
                    _dock = new Dock();
            }
        }
        return _dock;
    }

}