开发者

Does an entity model fire an event when its data changes?

I want to be notified when data changes within a particular table, represented by an entity model. Is 开发者_如何学编程the model aware of underlying data changes? If it does actually fire an event, how can I subscribe to it?


Your question is actually very unclear.

I want to be notified when data changes within a particular table, represented by an entity model.

What does it mean?

Do you want to be notified about changes in database not done by your application? Then the answer is: No EF doesn't provide any such notification system. You must build your own.

Do you want to be notified about changes you did to your entities? The the answer is INotifyPropertyChanged interface and ObservableCollection for navigation properties. use these constructs in your entities to be able to fire events when entity changes.

Do you want to know what changes will be executed in the database? Override SaveChanges or handle SavingChanges and use ObjectStateManager to get list of changed entities. Here is some example how to get list of added entities of given type.


The NuGet package EntityFramework.Triggers nicely wraps up functionality of subscribing to an Entity for inserts, updates, and deletions.

Just wrap your context with the DbContextWithTriggers;

public class MyContext : DbContextWithTriggers {
    public DbSet<Person> People { get; set; }
}

Then subscribe to trigger events

var mycontext  = new MyContext() { TriggersEnabled = true };
Triggers<Person>.Inserting += entry =>
{
    Console.WriteLine($"Person: {entry.Entity}");
};


No, there is no events fired on Change, only when you do SaveChanges you could catch what you need ...

for that, try looking at this question / answers


you can use Interceptors.

just inherit SaveChangesInterceptor and override SavingChangesAsync then listen SavedChanges event.

you should override SavingChanges ,because in SavedChanges all entry.State is EntityState.Unchanged

My code is just like this:

public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
{
    try
    {
        foreach (var entry in eventData.Context.ChangeTracker.Entries())
        {
            //when target entity is modified ,subscribe event
            if (entry.Entity is Device de && (entry.State == EntityState.Added || entry.State == EntityState.Deleted || entry.State == EntityState.Modified))
            {
                if (entry.State == EntityState.Modified)
                {
                    if (de.UseStatus.GetValueOrDefault(0) != (int)UseStatusConstType.IsCancel)
                    {
                        continue;
                    }
                }
                ModifiedDeviceId = de.Id;
                eventData.Context.SavedChanges -= Context_SavedChangesAsync;
                eventData.Context.SavedChanges += Context_SavedChangesAsync;
            }
        }
        return result;
    }
    catch (Exception ex)
    {
        _log.LogError(ex, "when entryState changing,try auto run function faild");
        return result;
    }
}

private async void Context_SavedChangesAsync(object sender, SavedChangesEventArgs e)
{
    //_log.LogInformation("current ModifiedDeviceId is  {ModifiedDeviceId} ", ModifiedDeviceId);

    try
    {               
        _log.LogInformation("in logger:{logger} for device:{deviceId},the state changed,now refresh device cache ", nameof(AutoRefreshDeviceCacheInterceptor), ModifiedDeviceId);

        //just do you want 

    }
    catch (Exception ex)
    {
        _log.LogError(ex, "in logger:{logger} after entryState changed,try auto run function faild", nameof(AutoRefreshDeviceCacheInterceptor));
    }
}

public override async ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
    try
    {
        eventData.Context.ChangeTracker.DetectChanges();
        foreach (var entry in eventData.Context.ChangeTracker.Entries())
        {
            if (entry.Entity is Device de && (entry.State == EntityState.Added || entry.State == EntityState.Deleted || entry.State == EntityState.Modified))
            {
                if (entry.State == EntityState.Modified)
                {
                    if (de.UseStatus.GetValueOrDefault(0) != (int)UseStatusConstType.IsCancel)
                    {
                        continue;
                    }
                }
                ModifiedDeviceId = de.Id;
                eventData.Context.SavedChanges -= Context_SavedChangesAsync;
                eventData.Context.SavedChanges += Context_SavedChangesAsync;
            }
        }
        return result;
    }
    catch (Exception ex)
    {
        _log.LogError(ex, "when entryState changing,try auto run function faild");
        return result;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜