c# - C# - 什么时候应创建new DbContext()

我目前使用的DbContext,类似于这样:


namespace Models


{


 public class ContextDB: DbContext


 {



 public DbSet<User> Users { get; set; }


 public DbSet<UserRole> UserRoles { get; set; }



 public ContextDB()


 {



 }


 }


}



然后,我在所有需要访问数据库的控制器顶部使用下面的行,在UserRepository类中也使用了它,它包含与用户(例如,获取活动用户,检查他拥有哪些角色,等等)相关的所有方法:


ContextDB _db = new ContextDB();



  • 当我创建一个新的DbContext/时,我应该有一个全局上下文?
  • 我可以在所有地方重用全局上下文吗?
  • 这会导致性能下降?
  • 别人是怎么做的?
时间:

我使用一个基本控制器,它公开了派生控制器可以访问的DataBase属性。


public abstract class BaseController : Controller


{


 public BaseController()


 {


 Database = new DatabaseContext();


 }



 protected DatabaseContext Database { get; set; }



 protected override void Dispose(bool disposing)


 {


 Database.Dispose();


 base.Dispose(disposing);


 }


}



我的应用程序中的所有控制器都是从BaseController派生的,并像这样使用:


public class UserController : BaseController


{


 [HttpGet]


 public ActionResult Index()


 {


 return View(Database.Users.OrderBy(p => p.Name).ToList());


 }


}



现在回答你的问题:

当我应该创建一个新的DbContext/时,我应该有一个全局上下文?

应根据每个请求创建上下文,创建上下文后,做需要做的事情,然后去掉它。

不要尝试使用全局上下文(这不是Web应用程序的工作方式)。

我可以在所有地方使用一个全局上下文?

不。如果你保持一个上下文,它将跟踪所有的更新、添加、删除等,这将减慢你的应用程序速度,甚至可能导致一些非常微妙的错误出现在你的应用程序中。

我个人喜欢直接将DbContext公开为大多数存储库示例,我看到的只是DbContext的薄包装。

这会导致性能下降?

第一次创建DbContext代价是相当昂贵的,但是,一旦完成了,很多的信息被缓存,以便后续的实例化,当你每次需要访问数据库时,你都可能会看到性能问题,而不是从实例化上下文。

现在我正在尝试这种方法,它避免了在调用不使用它的操作时实例化上下文。


public abstract class BaseController : Controller


{


 public BaseController() { }



 private DatabaseContext _database;


 protected DatabaseContext Database


 {


 get


 {


 if (_database == null)


 _database = new DatabaseContext();


 return _database;


 }


 }



 protected override void Dispose(bool disposing)


 {


 if (_database != null)


 _database.Dispose();


 base.Dispose(disposing);


 }


}



这显然是一个老问题,但是,如果你使用DI,则可以在请求生存期内执行所有对象,


 public class UnitOfWorkAttribute : ActionFilterAttribute


 {


 public override void OnActionExecuting(HttpActionContext actionContext)


 {


 var context = IoC.CurrentNestedContainer.GetInstance<DatabaseContext>();


 context.BeginTransaction();


 }



 public override void OnActionExecuted(HttpActionExecutedContext actionContext)


 {


 var context = IoC.CurrentNestedContainer.GetInstance<DatabaseContext>();


 context.CloseTransaction(actionContext.Exception);


 }


 }



...