Nipuna
Nipuna

Reputation: 7006

How to keep DbContext in Connected state with Web API

Since Web APIs are stateless when you have EF Core backend after any request the DbContext would be disconnected.

Therefore we have made QueryTracking as NoTracking since default behavior TrackAll doesn't give any benefit since its a web application

DbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

Is there anyway to keep DbContext in connected state when using over a Web API?

E.g:

Is there a way to reuse/keep in connected state for the above scenario?

Upvotes: 1

Views: 874

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239260

You seem to be suffering under a number of misconceptions/misunderstandings. First, connections are entirely separate from tracking, state, and everything else here honestly. Particularly if you employ connection pooling, the same database connection may very well be used across many different requests and even context instances. Just because the context is disposed does not mean that the connection to the database is also closed. Likewise, instantiating a context doesn't always equate to a new connection being established.

Second, query tracking has to do with the object cache EF keeps and the change tracking it does. Turning this feature off can have some perf benefits as the cache and change tracking do consume some amount of resources. However, it can also negatively impact performance, depending on the type of queries you're doing. The object cache in particular can prevent subsequent queries from even needing to be issued, if the objects have already been retrieve via other means. But, importantly, the object cache is intimately tied to the context instance, and therefore has the same lifetime as the context itself. It does not persist across requests, which you seem to understand, but it does persist across operations done within a single request pipeline, which you seem to not understand. The context could potentially be utilized any number of times during a single request, so there is still value in the query tracking. Rather than turn it off completely, you should pick and choose on a case by case basis when to not employ it via adding .AsNoTracking() to the query, if it makes sense to do that in that particular circumstance.

Third, HTTP is stateless, not just Web APIs. Even traditional HTML returning web applications are stateless. Things like Session are fake state. Each HTTP request is completely unique, unconcerned and unaffected by anything that has happened before or since between the client and the server. In the case of sessions, auth, etc. an identifier is transferred to the client from the server (a cookie), and the client sends that back to the server with each subsequent request. That allows the illusion of state, but it's really being established anew each time.

As such, there is no way to persist the results of query between requests, save from using something like Session or a cache. Even then, the result for your purposes here would not work, as the data would have to be serialized/deserialized, removing any ties to any sort of state tracking, i.e. it's just data, and EF, for example, would know nothing about it or how to persist changes to it.

Upvotes: 8

Related Questions