Entity Framework Core 中的 ObjectStateManager.ObjectStateManagerChanged

Mur*_*ock 5 c# entity-framework entity-framework-core

我似乎无法ObjectStateManager.ObjectStateManagerChanged在 ef 核心中找到。这是否已被删除,如果是,有什么替代方案?

我想在实体加载到上下文时收到通知。

Iva*_*oev 4

目前(最新官方 EF Core v1.1.2)没有公开的替代方案。有计划公开Lifetime Hooks,但根据EF Core 路线图,它们被推迟,并且不会在即将发布的 v2.0 版本中提供。

幸运的是,EF Core 公开了所有内部基础结构类/接口,因此我可以在典型的 EF Core 内部使用免责声明下建议以下解决方法

此 API 支持 Entity Framework Core 基础结构,并不适合直接在您的代码中使用。此 API 可能会在未来版本中更改或删除。

我想到的是利用Microsoft.EntityFrameworkCore.ChangeTracking.Internal命名空间,更具体地说ILocalViewListener是提供以下方法的接口

void RegisterView(Action<InternalEntityEntry, EntityState> viewAction)
Run Code Online (Sandbox Code Playgroud)

允许viewAction您注册委托,该委托将在任何实体状态更改时调用,包括附加、添加、删除、分离等。

因此,在DbContext派生类构造函数中,您可以获取ILocalViewListener服务并注册处理程序,如下所示:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在处理程序内部,如果您更喜欢使用常规对象而不是内部类,则还可以使用该InternalEntityEntry.ToEntityEntry()方法来获取常规EntityEntry对象(类似于DbContext.Entry和方法) 。ChangeTracker.EntriesInternalEntityEntry

在 EF Core v1.1.2 中测试并工作。