在ASP.NET管理实体框架的ObjectContext [英] Managing Entity Framework ObjectContext in ASP.NET

查看:146
本文介绍了在ASP.NET管理实体框架的ObjectContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用实体框架的ASP.NET Web窗体应用程序,我不知道我应该如何处理的ObjectContext 和它的使用寿命。 例如,我有一个 InviteService 类管理的邀请,如创建和接受邀请。类本身就是从Web项目中的另一个项目/命名空间。 一个 InviteUsers()方法创建一个邀请实体为用户的列表,调用库将它们保存到数据库中,邮件每个用户的邀请链接。

I'm using the Entity Framework for an ASP.NET Web Forms application and I'm wondering how I should deal with ObjectContext and it's lifetime. For example, I have an InviteService class that manages invites such as creating and accepting invites. The class itself is in another project/namespace from the Web project. An InviteUsers() method creates Invite entities for a list of users, calls a repository to save them to the database and mails each user an invite link.

该方法是从所谓的当用户点击邀请按钮。

The method is called from the Page when a user clicks the invite button.

我想知道我应该怎么使用的ObjectContext

I would like to know how I should use the ObjectContext

  1. 构造一个新的的ObjectContext 在页面上的每个请求,将它作为一个参数的构造函数中的 InviteService 类,然后在处理它的渲染方法。
  2. 在与上面相同的,而不是通过构造函数设置它,以及将它作为参数传递给每个方法,但
  3. 创建一个单独的的ObjectContext 中的每个方法与使用块。
  1. Instantiate a new ObjectContext on the Page on each Request, passing it as a parameter to the constructor of the InviteService class and then disposing it in the Render method.
  2. Same as above but instead of setting it via the constructor, passing it along as a parameter to each method.
  3. Create a separate Objectcontext in each method with a using block.

方案一似乎最好是我根据拉吉斯拉夫这里的答案是:<一href="http://stackoverflow.com/questions/3653009/entity-framework-and-connection-pooling/3653392#3653392">Entity框架和连接池 但是选项3似乎也有效,因为据我所知,没有新的数据库连接,因为连接池进行。

Option one seems best to me based on the answer of Ladislav here: Entity Framework and Connection Pooling But option 3 seems valid as well since as far as I know, no new database connections are made because of connection pooling.

推荐答案

这是不寻常的每个Web请求创建一个的ObjectContext 。我这样做是在我的Web应用程序。然而,海事组织,页面应该一无所知的ObjectContext

It is not unusual to create a single ObjectContext per web request. I do this in my web applications. However, IMO, the page should know nothing about the ObjectContext.

既然你已经在谈论注射在服务的构造背景下,看看依赖注入(如果你不使用的话)。当您使用依赖注入容器,可以让容器创建为您服务,在该容器中的对象上下文注入。你的页面必须做的唯一事情是从容器中请求服务(理想情况下,你甚至可以让在该页面的构造函数的服务被注入,但是这是不可能的Web表单)。

Since you are already talking about injecting the context in the constructor of the service, take a look at dependency injection (if you aren't using that already). When you use a dependency injection container, you can let the container create that service for you and inject the object context in that container. The only thing your page has to do is request that service from the container (ideally, you would even let that service be injected in the constructor of that page, but this is not possible with web forms).

您的网页是这样的:

public class MyPage : Page
{
    private readonly IMyService service;

    public MyPage()
    {
        this.service = Global.GetInstance<IMyService>();
    }

    protected void Btn1_OnClick(object s, EventArgs e)
    {
        this.service.DoYourThing(this.TextBox1.Text);
    }
}

在应用程序的启动路径(Global.asax中),您可以配置依赖注入框架是这样的:

In the startup path (Global.asax) of your application, you can configure the Dependency Injection framework like this:

private static Container Container;

public static T GetInstance<T>() where T : class
{
    return container.GetInstance<T>();
}

void Application_Start(object sender, EventArgs e) 
{
    var container = new Container();

    string connectionString = ConfigurationManager
        .ConnectionStrings["MyCon"].ConnectionString;

    // Allow the container to resolve your context and
    // tell it to create a single instance per request.
    container.RegisterPerWebRequest<MyContext>(() =>
        new MyContext(connectionString));

    // Tell the container to return a new instance of
    // MyRealService every time a IMyService is requested.
    // When MyContext is a constructor argument, it will
    // be injected into MyRealService.
    container.Register<IMyService, MyRealService>();

    Container = container;
}

在这些例子中我用href="https://simpleinjector.org" rel="nofollow">简单的注射器依赖注入容器的 RegisterPerWebRequest 是不属于核心库,但是的可作为(的NuGet)扩展包。该软件包确保您的的ObjectContext web请求结束时被设置。

In these examples I used the Simple Injector dependency injection container, although any DI container will do. The RegisterPerWebRequest is not part of the core library, but is available as (NuGet) extension package. The package ensures that your ObjectContext is disposed when the web request ends.

这可能看起来很复杂在第一,但这样的网页并不担心在所有关于创造和处置的的ObjectContext 的任何细节。

This might seem complex at first, but this way the web page doesn't have to worry at all about any details of creating and disposing an ObjectContext.

另外,放置在一个单独的类执行用例的逻辑:一个命令。让命令(或系统)确保操作atomicness。不要让网页负责这个,不承担任何责任的请求结束,因为在这一点上,你会不知道,如果它甚至确定调用commit。不,我们的命令处理这本身。这里是有关编写业务的文章命令

Further, place the logic that executes a use case in a single class: a command. Let the command (or the system) ensure atomicness of that operation. Don't let the page be responsible for this, and don't commit on the end of the request, because at that point you won't know if it is even OK to call commit. No, let the command handle this itself. Here is an article about writing business commands.

这提示适用于ASP.NET MVC为好,但你不应该叫 Global.GetInstance&LT; IMyService&GT;()控制器的构造函数中,而只是用构造函数注入(因为MVC有这个伟大的支持),并使用 MVC3集成包

This advice holds for ASP.NET MVC as well, although you should not call Global.GetInstance<IMyService>() inside the Controller's constructor, but simply use constructor injection (since MVC has great support for this) and use the MVC3 Integration package.

另外看看<一href="https://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why/10588594#10588594">this计算器的问题,其中谈到了每个请求之间的 IObjectContextFactory 或具有的ObjectContext 选择。

Also take a look at this Stackoverflow question, which talks about choosing between a IObjectContextFactory or having a ObjectContext per request.

这篇关于在ASP.NET管理实体框架的ObjectContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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