繁体   English   中英

实体 model 是否在其数据更改时触发事件?

[英]Does an entity model fire an event when its data changes?

我想在特定表中的数据更改时收到通知,由实体 model 表示。 model 是否知道底层数据更改? 如果它确实触发了一个事件,我该如何订阅它?

你的问题其实很不清楚。

我希望在特定表中的数据更改时得到通知,由实体模型表示。

这是什么意思?

您是否希望收到有关您的应用程序未完成的数据库更改的通知? 然后答案是:没有EF不提供任何此类通知系统。 你必须建立自己的。

您是否希望收到有关您对实体所做更改的通知? 答案是INotifyPropertyChanged接口和ObservableCollectio n用于导航属性。 在实体中使用这些构造,以便在实体更改时触发事件。

您想知道将在数据库中执行哪些更改吗? 覆盖SaveChanges或处理SavingChanges并使用ObjectStateManager获取已更改实体的列表。 以下是如何获取给定类型的已添加实体列表的一些示例。

NuGet包EntityFramework.Triggers很好地包含了订阅实体以进行插入,更新和删除的功能。

用DbContextWithTriggers包装你的上下文;

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

然后订阅触发事件

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

不,没有事件在Change上被触发,只有当你做SaveChanges你才能捕捉到你需要的东西......

为此,试着看看这个问题/答案

如果您的目的是仅在有更改时保存数据,请参阅以下链接:

http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.savingchanges.aspx

你可以使用拦截器

只需继承SaveChangesInterceptoroverride SavingChangesAsync然后监听SavedChanges事件。

你应该override SavingChanges ,因为在SavedChanges所有entry.StateEntityState.Unchanged

我的代码是这样的:

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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM