且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ASP.Net Core MVC存储库模式意外处置

更新时间:2023-02-13 17:29:44

您的存储库和DbContext都不应该是单例.正确注册它们的方法是services.AddScopedservices.AddTransient,因为DbContext的生存期不应长于请求,而AddScoped正是为此而存在的.

Neither your repository nor your DbContext should be singletons. The correct way to register them is services.AddScoped or services.AddTransient, as a DbContext shouldn't live longer than a request and the AddScoped is exactly for this.

AddScoped将在范围的生存期内(在ASP.NET Core中等于请求的生存期)返回DbContext的相同实例(如果您是这样注册的,则返回存储库).

AddScoped will return the same instance of a DbContext (and repository if you register it as such) for the lifetime of the scope (which in ASP.NET Core equals the lifetime of a request).

使用AddScope时,您不要自己处置上下文,因为解析存储库的下一个对象将具有处置的上下文.

When you use AddScope you shouldn't dispose the context yourself, because the next object that resolves your repository will have an disposed context.

默认情况下,Entity Framework将上下文注册为作用域,因此您的存储库应为作用域(与上下文和请求相同的生存期)或临时的(每个服务实例获取其自身的存储库实例,但请求中的所有存储库仍共享相同的上下文).

Entity Framework by default registers the context as scoped, so your repository should be either scoped (same lifetime as the context and request) or transient (each service instance gets it's own instance of the repository, but all repositories within a request still share the same context).

使上下文单例成为一个严重的问题,尤其是在内存方面(您处理的越多,上下文消耗的内存就越多,因为它必须跟踪更多的记录).因此,DbContext应该尽可能短.

Making the context singleton causes serious issues, especially with the memory (the more you work on it, the more memory the context consumes, as it has to track more records). So a DbContext should be as short-lived as possible.

上下文的持续时间的优点是,如果出现问题,您仍然可以回滚请求期间的所有操作,并将其作为一个事务处理.

Duration of the context has the advantage that you can still roll back all operations during the request if something goes wrong and handle it as one single transaction.