首页 文章

在MVC中根据请求使用Owin DbContext的实体框架

提问于
浏览
5

我注意到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

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

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

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

  • 0

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

相关问题