实体框架:代码第一。共享和实例上下文 [英] Entity Framework: Code First. Shared and Instance context

查看:137
本文介绍了实体框架:代码第一。共享和实例上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用具有mvc4 Web应用程序的Entity Framework代码第一种方法构建分层应用程序,主要分为数据服务 Web



从我的网站我这样做:

  public void Foo(){
EntityService _svc = new EntityService();
Entity = _svc.FindById(1);
}

服务方法如下所示:

  private readonly MyContext _ctx = new MyContext(); 

public Entity FindById(long id){
return _ctx.Entities.SingleOrDefault(q => q.EntityId == id);
}

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



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

  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;
}
}

更改了我的服务,如下所示:

  public class EntityService 
{
private readonly MyContext _ctx;

public bool SharedContext {get;私人集合

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();
}
}

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

  EntityService _entitySvc = new EntityService(true,true); 
AnotherEntityService _anotherEntitySvc = new AnotherEntityService(true);

这至少是一个体面的方法来克服这个吗?我会感谢提供的任何帮助。谢谢。

解决方案

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



这是Dependency注射真正发光的情况之一。通过依赖关系注入,您可以管理数据上下文的生命周期,并使其在请求的生命周期中生效,而不是静态的应用程序池的生命周期。



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



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



然而,我强烈建议您通过依赖注入进行此操作。


I'm building a layered application using Entity Framework code first approach with an mvc4 web application, separated mainly in Data, Services, and Web.

From my web I do this:

public void Foo() {
    EntityService _svc = new EntityService();
    Entity = _svc.FindById(1);
}

The service method looks like this:

private readonly MyContext _ctx = new MyContext();

public Entity FindById(long id) {
    return _ctx.Entities.SingleOrDefault(q => q.EntityId == id);
}

The problem is when I need to use more than one service because each service will create it's own context.

Trying to solve this I did something like this:

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;
    }
}

Changed my services as follows:

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();
    }
}

Now if I want to share an instance of my context, I'd do something like this:

EntityService _entitySvc = new EntityService(true, true);
AnotherEntityService _anotherEntitySvc = new AnotherEntityService(true);

Is this, at least, a decent way to overcome this? I'll appreciate any help provided. Thanks.

解决方案

Never ever ever ever ever ever ever ever... ever... did I mention ever? I mean it. Never ever create a static data context. Never ever. Really. Can I stress this any more? Never. Don't even think about it. Thinking about it will give you brain cancer.

This is one of the situations in which Dependency injection really shines. With Dependency injection, you can manage the lifetime of your data contexts and make them live for the lifetime of the request, rather than the lifetime of the app pool, as a static does.

To elaborate on why a shared context is bad. Not only is the context shared among your classes, but also among threads and requests. That means two users using the site at the same time will stomp all over each others data context, causing all kinds of problems. Data contexts are NOT thread safe, and they're not concurrent safe.

If you want to share your data context with multiple objects, then you need to pass it in to those objects, either as part of a method call, or as a constructor argument.

I highly recommend doing this via Dependency Injection, however.

这篇关于实体框架:代码第一。共享和实例上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆