MVC中每个请求使用Owin DbContext的实体框架

时间:2016-03-14 19:36:40

标签: c# asp.net-mvc entity-framework owin dbcontext

我注意到MVC的项目模板在使用单个用户帐户时会在当前Owin上下文中放置一些对象(在App_Start/Startup.Auth.cs中):

// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

看起来这是访问数据库中的Identity功能。我的理解是,每个请求创建一个ApplicationDbContext实例,并通过整个管道重新使用。用我自己的实体框架DbContext做同样的事情是否有益?

例如,我在App_Start/Startup.Data.cs中创建了一个新文件:

public partial class Startup
{

    public void ConfigureData(IAppBuilder app)
    {

        app.CreatePerOwinContext(CreateParkingEntities);

    }

    protected ParkingEntities CreateParkingEntities()
    {
        return new ParkingEntities();
    }

}

然后在Startup.cs

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
        ConfigureData(app);
    }
}

然后我可以在我的控制器中使用上下文:

private ParkingEntities _db;

public ParkingEntities DbContext
{
    get
    {
        return _db ?? HttpContext.GetOwinContext().Get<ParkingEntities>();
    }
    private set
    {
        _db = value;
    }
}

我认为如果这是标准做法,实体框架会有一些脚手架,但它只是在控制器级别创建一个实例。是否可以安全地假设如果DbContext仅从该控制器访问,那么它在功能上等同于上述实现并将其置于Owin管道中是否过度了?

我认为如果需要额外的设置,这种方法的另一种用法是DbContext的单个初始化点。

2 个答案:

答案 0 :(得分:0)

使用EF db-context的主要方法很简单:连接到db-context,获取数据并忘记这个db-context对象。 EF上下文是IDisposable并在dispose之后关闭连接(不要忘记使用(){})。这意味着,当您需要数据库连接时,可以在应用程序的任何位置创建EF数据上下文。您可以在控制器操作中创建新的db-context,如果他们正在使用您的数据库。一切都取决于您的应用程序的架构。如果您确定,对您的应用程序的所有请求都需要许多db操作,我认为您的每个owin-context的db-context解决方案都很有用。

答案 1 :(得分:0)

DbContext旨在实现轻量级,因此每次需要时都不会花费太多成本来创建新实例。主要成本是重新创建连接和垃圾收集您正在创建的所有实例。

请注意,如果您在DbSets上使用Find()方法,它将缓存结果,因此下次您要求时,它不需要转到数据库。如果重新使用相同的上下文,则可以利用该缓存,但如果创建新上下文,则会丢失缓存。

如果将DbContext存储在控制器的实例成员中,那么它将仅用于一个请求,因为将为每个请求创建一个新的控制器实例。只要确保你不要把它放在静态成员中 - 我希望如果你这样做,你会得到各种各样的竞争条件。

相关问题