I can't seem to find ObjectStateManager.ObjectStateManagerChanged
in ef core. Has this been removed and if so what is the alternative?
I want to be notified whenever an entity is loaded into the context.
To use Entity Framework 6, your project has to compile against . NET Framework, as Entity Framework 6 doesn't support . NET Core. If you need cross-platform features you will need to upgrade to Entity Framework Core.
EF 6 is a stable and mature ORM while EF Core is relatively new. Microsoft rebuilt EF Core from the ground up and removed many of the internal dependencies and providers that EF 6 had (like SQLClient). In the long run, that will make EF Core much more extensible and lighter weight.
EF Core is an object-relational mapper (ORM). Object-relational mapping is a technique that enables developers to work with data in object-oriented way by performing the work required to map between objects defined in an application's programming language and data stored in relational datasources.
Currently (the latest official EF Core v1.1.2) there is no public alternative. There are plans to expose Lifetime Hooks, but according to EF Core Roadmap they are postponed and will not be available in the upcoming v2.0 release.
Luckily EF Core exposes all the internal infrastructure classes/interfaces, so I could suggest the following workaround under the typical EF Core internals usage disclaimer
This API supports the Entity Framework Core infrastructure and is not intended to be used directly from your code. This API may change or be removed in future releases.
What I have in mind is utilizing the Microsoft.EntityFrameworkCore.ChangeTracking.Internal
namespace, and more specifically the ILocalViewListener
interface which provides the following method
void RegisterView(Action<InternalEntityEntry, EntityState> viewAction)
The viewAction
allows you to register delegate which will be called on any entity state change, including attaching, adding, deleting, detaching etc.
So inside your DbContext
derived class constructor, you could obtain ILocalViewListener
service and register the handler like this:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
public class MyDbContext : DbContext
{
// ...
public MyDbContext()
{
this.GetService<ILocalViewListener>()?.RegisterView(OnStateManagerChanged);
}
void OnStateManagerChanged(InternalEntityEntry entry, EntityState previousState)
{
if (previousState == EntityState.Detached && entry.EntityState == EntityState.Unchanged)
{
// Process loaded entity
var entity = entry.Entity;
}
}
}
Inside the handler, you can also use the InternalEntityEntry.ToEntityEntry()
method to get the regular EntityEntry
object (similar to DbContext.Entry
and ChangeTracker.Entries
methods) if you prefer working with it rather than the internal InternalEntityEntry
class.
Tested and working in EF Core v1.1.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With