[英]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
你可以使用拦截器。
只需继承SaveChangesInterceptor
并override
SavingChangesAsync
然后监听SavedChanges
事件。
你应该override
SavingChanges
,因为在SavedChanges
所有entry.State
是EntityState.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.