在ASP.NET中管理实体框架ObjectContext

Fre*_*eek 4 .net asp.net ado.net entity-framework objectcontext

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

Page用户单击邀请按钮时调用该方法.

我想知道我该怎么用 ObjectContext

  1. ObjectContext在每个Request上的Page上实例化一个new ,将其作为参数传递给InviteService类的构造函数,然后将其置于Render方法中.
  2. 与上面相同,但不是通过构造函数设置它,而是将它作为参数传递给每个方法.
  3. Objectcontext使用using块在每个方法中创建单独的.

根据Ladislav的答案,选项一对我来说似乎最好:实体框架和连接池 但是选项3似乎也是有效的,因为据我所知,由于连接池没有建立新的数据库连接.

Ste*_*ven 6

ObjectContext每个Web请求创建一个单一的请求并不罕见.我在我的网络应用程序中这样做.但是,IMO,页面应该一无所知ObjectContext.

由于您已经在讨论在服务的构造函数中注入上下文,请查看依赖注入(如果您尚未使用它).使用依赖项注入容器时,可以让容器为您创建该服务,并在该容器中注入对象上下文.您的页面唯一要做的就是从容器中请求该服务(理想情况下,您甚至可以将该服务注入该页面的构造函数中,但这对于Web表单是不可能的).

您的页面如下所示:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

在这些示例中,我使用了Simple Injector依赖注入容器,尽管任何DI容器都可以.的RegisterPerWebRequest是不是核心库的一部分,但可作为(的NuGet)扩展包.该程序包可确保ObjectContext在Web请求结束时将其处理.

这可能看起来很复杂,但这样一来,网页就不必担心创建和处理任何细节了ObjectContext.

此外,将执行用例的逻辑放在单个类中:命令.让命令(或系统)确保该操作的原子性.不要让页面对此负责,并且不要在请求结束时提交,因为此时您不会知道是否可以调用commit.不,让命令自己处理.这是一篇关于编写业务命令的文章.

这个建议也适用于ASP.NET MVC,虽然你不应该Global.GetInstance<IMyService>()在Controller的构造函数内部调用,但只需使用构造函数注入(因为MVC对此有很大的支持)并使用MVC3 Integration包.

也看看这个问题#1,其中谈到之间选择IObjectContextFactory或有ObjectContext每个请求.