由于在任何请求后具有EF Core后端的Web API都是无状态的,因此DbContext将被断开。
因此,我们将QueryTracking
设为NoTracking
,因为默认行为TrackAll
自从成为Web应用程序以来没有任何好处
DbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
在通过Web API使用时,是否仍可以使DbContext保持连接状态?
例如:
在上述情况下,是否可以重用/保持连接状态?
答案 0 :(得分:7)
您似乎正遭受许多误解/误解。首先,连接完全独立于跟踪,状态和其他所有内容。特别是如果您使用连接池,则很可能在许多不同的请求甚至上下文实例之间使用同一数据库连接。仅因为处理了上下文并不意味着与数据库的连接也已关闭。同样,实例化上下文并不总是等同于建立新的连接。
第二,查询跟踪与EF保留的对象缓存及其所做的更改跟踪有关。关闭此功能可能会带来一些好处,因为缓存和更改跟踪确实会消耗一些资源。但是,它也会对性能产生负面影响,具体取决于您正在执行的查询的类型。如果对象缓存已经通过其他方式检索,则对象缓存尤其可以防止后续查询的发出。但是,重要的是,对象缓存与上下文实例紧密相关,因此具有与上下文本身相同的生存期。它不会在您似乎理解的请求中持久存在,但是会在单个请求管道中完成的操作中持久存在,您似乎不理解。在单个请求期间,该上下文可能会被多次利用,因此查询跟踪中仍然有价值。除了在特定情况下可以使用.AsNoTracking()
之外,您还应根据情况选择不使用它,而不是完全关闭它。
第三, HTTP 是无状态的,而不仅仅是Web API。甚至传统的返回HTML的Web应用程序都是无状态的。像Session
之类的东西都是假状态。每个HTTP请求都是完全唯一的,不受客户端和服务器之间或客户端与服务器之间发生的任何事情的影响和影响。在会话,身份验证等情况下,标识符从服务器(cookie)传输到客户端,然后客户端将其与每个后续请求一起发送回服务器。这让国家产生了错觉,但实际上每次都在重新建立它。
因此,除了使用Session
之类的东西或缓存之外,无法保留请求之间的查询结果。即使那样,您在这里得到的结果也不起作用,因为必须对数据进行序列化/反序列化,消除与任何类型的状态跟踪的联系,即仅仅是数据,例如,EF对它一无所知或如何保留更改。