Should DbContext be short-lived (you spin up a new one for every unit of work) or should I just use a singleton throughout the entire application? I see a lot of conflicting info on this. Lots of people say it should be short lived, OTOH microsoft seems to suggest the opposite:

When working with Windows Presentation Foundation (WPF) or Windows Forms, use a context instance per form. This lets you use change-tracking functionality that context provides.
Which one is it?

How does change tracking work if I use a different context every time, it doesn’t actually carry over between contexts right?

It should be short lived. I think they mean something like this: the users clicks something like “edit customer”. A new “form” (window) with a context is created. The user changes a few fields and presses “save changes”. You call SaveChanges() on the context and dispose it. The main window of an app which could stay open for days should not have a context. It should create a new one each time it loads or saves data.

I don’t personally like the “dbcontext per form” suggestion. I much prefer to create services that are more closely related to web services with the exception that you are calling them directly instead of via a HTTP or gRPC call. The biggest downside of this method is you lose the benefits of the ASP.NET Core framework – you do not get the automatic scoping for your DI.

I use MediatR in the scenario since each instance of a MediatR handler is instantiated per call, you can inject your DbContext into the MediatR handler and get the required short life of your context.

Why are we working so hard to avoid using the change tracker for what it’s worth? It’s like built-in automatic caching and “undo” functionality and we just nuke it out our system design as much as possible.

One instance per form is slightly longer than one per unit of work. But if you have multiple forms it’s still not a singleton. Change tracking is usually done by adding a special column to your database-table that holds the rowversion. Entity framework then throws an exception when the rowversion doesn’t match.

source