gpt4 book ai didi

c# - 如何确定 Dbcontexts 的范围(以防止整个应用程序的单例上下文)

转载 作者:可可西里 更新时间:2023-11-01 08:43:14 25 4
gpt4 key购买 nike

我想知道您如何在 Entity Framework 中确定 Dbcontext 的范围,这样您就不会为整个应用程序使用单个 Dbcontext。我是 Entity Framework 的新手并且一直在阅读教程,但他们都使用单个 Dbcontext 作为示例,因此 EF 现在对我来说几乎是一个黑盒子。

例如我有 3 个模型:

  • 发布
  • 用户
  • 评论

每个模型都相互关联(A Post 属于 User,Comment 属于 User 和 Post)。我是否为每个单独创建一个 Dbcontext?但这是不正确的,因为它们都是相关的,或者我会为我需要的每个场景创建一个 Dbcontext 吗?例如,如果我只需要查询 Post 和 Comments 而不是用户,那将是一个 PostCommentsContext。然后我们会有一个 PostUserCommentContext...

最佳答案

最好的解决方案是使用工作单元来包装数据上下文,以及管理连接生命周期并允许您使用多个存储库(如果您愿意的话)沿着那条路走下去)。

实现总结:

  • 创建一个接口(interface) (IUnitOfWork),它公开您的 DbSet 的属性,以及一个名为 Commit 的方法
  • 创建一个实现 (EntityFrameworkUnitOfWork),按要求实现。 Commit 只需调用基类 (DbContext) 上的 SaveChanges,并且还为最后一分钟的逻辑提供了一个很好的 Hook 。
  • 您的 Controller 接受 IUnitOfWork,使用 DI(最好)解析 EntityFrameworkUnitOfWork,具有 HTTP 上下文作用域生命周期 设置(StructureMap对此有好处)
  • (可选,但推荐)创建一个 Repository,它也采用 IUnitOfWork,并通过您的 Controller 处理它。

HTH

编辑 - 回应评论

Oh, how can you do work that involves creating records in multiple models then? i.e., create a new user and a new post in the same transaction.

鉴于您使用的是 ASP.NET MVC,您的 Controller 应该在其构造函数中接受 IUnitOfWork

根据您的要求,这是一个例子

public SomeController : Controller
{
private IUnitOfWork _unitOfWork;
private IUserRepo _userRepo;
private IPostRepo _postRepo;

public SomeController(IUnitOfWork unitOfWork, IUserRepo userRepo, IPostRepo postRepo)
{
_unitOfWork = unitOfWork; // use DI to resolve EntityFrameworkUnitOfWork
_userRepo = userRepo;
_postRepo = postRepo;
}

[HttpPost]
public ActionResult CreateUserAndPost(User user, Post post)
{
// at this stage, a HTTP request has come in, been resolved to be this Controller
// your DI container would then see this Controller needs a IUnitOfWork, as well
// as two Repositories. DI smarts will resolve each dependency.
// The end result is a single DataContext (wrapped by UoW) shared by all Repos.
try
{
userRepo.Add(user);
postRepo.Add(post);
// nothing has been sent to DB yet, only two objects in EF graph set to EntityState.Added
_unitOfWork.Commit(); // two INSERT's pushed to DB
}
catch (Exception exc)
{
ModelState.AddError("UhOh", exc.ToString());
}
}
}

And one more question, what does the HTTP-context scoped lifetime do?

DI-talk 中的对象具有范围管理设置,包括每个线程、每个 session 、每个 http 请求、单例等。

HTTP 上下文范围是 Web 应用程序的推荐设置。它的意思是“当一个 HTTP 请求进来时新建一个上下文,并在请求完成时摆脱它”。

关于c# - 如何确定 Dbcontexts 的范围(以防止整个应用程序的单例上下文),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4822278/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com