实体框架:代码优先.共享和实例上下文

Est*_*ban 2 c# entity-framework ef-code-first

我建设使用实体框架代码首先与mvc4 Web应用程序的方式分层的应用,主要是分开的Data,ServicesWeb.

从我的网站上我这样做:

public void Foo() {
    EntityService _svc = new EntityService();
    Entity = _svc.FindById(1);
}
Run Code Online (Sandbox Code Playgroud)

服务方法如下所示:

private readonly MyContext _ctx = new MyContext();

public Entity FindById(long id) {
    return _ctx.Entities.SingleOrDefault(q => q.EntityId == id);
}
Run Code Online (Sandbox Code Playgroud)

问题是当我需要使用多个服务时,因为每个服务都会创建它自己的上下文.

试图解决这个问题我做了这样的事情:

public class MyContext : DbContext {
    private static MyContext _ctx;

    public MyContext() : base("name=myConnectionString") { }

    public static MyContext GetSharedInstance() {
        return GetSharedInstance(false);
    }

    public static MyContext GetSharedInstance(bool renew) {
        if(_ctx == null || renew)
            _ctx = new MyContext();

        return _ctx;
    }
}
Run Code Online (Sandbox Code Playgroud)

改变我的服务如下:

public class EntityService
{
    private readonly MyContext _ctx;

    public bool SharedContext { get; private set; }

    public EntityService()
        : this(false) { }

    public EntityService(bool sharedContext)
        : this(sharedContext, false) { }

    public EntityService(bool sharedContext, bool renew)
    {
        SharedContext = sharedContext;

        if (SharedContext)
            _ctx = MyContext.GetInstance(renew);
        else
            _ctx = new MyContext();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想分享我的上下文的实例,我会做这样的事情:

EntityService _entitySvc = new EntityService(true, true);
AnotherEntityService _anotherEntitySvc = new AnotherEntityService(true);
Run Code Online (Sandbox Code Playgroud)

这至少是一个克服这个问题的好方法吗?我将不胜感激任何帮助.谢谢.

Eri*_*sch 10

永远不会永远......永远......我曾经提到过吗?我是认真的.永远不要创建静态数据上下文.永远不能.真.我可以再强调一下了吗?决不.甚至不要考虑它.考虑它会给你脑癌.

这是依赖注入真正发挥作用的情况之一.使用依赖注入,您可以管理数据上下文的生命周期,并使其在请求的生命周期内生效,而不是像静态一样使用应用程序池的生命周期.

详细说明共享上下文为何不好.不仅在您的类之间共享上下文,而且在线程和请求之间共享.这意味着同时使用该站点的两个用户将会踩到彼此的数据上下文,从而导致各种问题.数据上下文不是线程安全的,并且它们不是并发安全的.

如果要与多个对象共享数据上下文,则需要将其作为方法调用的一部分或作为构造函数参数传递给这些对象.

但我强烈建议通过依赖注入执行此操作.