为什么我获取的数据查看的是旧数据库数据而不是数据库的更新数据?
Why is my fetch data looking at old database data instead of updated data of database?
我有一个计时器,每 10 秒计时一次。
计时器结束后,它将调用我的服务,然后获取数据
从我的服务并将其分配给我的 radzen table 然后 StateHasChanged 将
重新呈现页面并更新更改。
@using System.Timers;
Timer _timer;
protected override async Task OnInitializedAsync()
{
StartTimer();
}
private void StartTimer()
{
_timer = new System.Timers.Timer();
_timer.Interval = 10000; //every 10 seconds
_timer.Elapsed += DashboardTimerElapsed;
_timer.Start();
}
private async void DashboardTimerElapsed(Object source, ElapsedEventArgs e)
{
await FetchData();
}
private async Task FetchData()
{
dashboardData = await getDataService.GetDataAsync();
await InvokeAsync(StateHasChanged);
}
计时器已过且一切正常,我遇到的唯一问题是如果我的应用程序是 运行,我对数据库中的一个数据进行了更改,例如:更改值名称“shazam”到“沙赞”。在过去时,我的新数据应该拉下“shazamm”,但是当我查看 dashbardData 时,我可以看到它没有拉下“shazamm”,而是拉下“shazam”,我认为这是 dbcontext 的旧实例。 (顺便说一句,我的 dbcontext 是有范围的)-
services.AddDbContext<DbContext>(options => {
options.UseSqlServer(Configuration.GetConnectionString("DbContextURL"));
}, ServiceLifetime.Scoped);
任何人都可以看到我哪里错了并帮助我吗?谢谢!
计时器事件将在与计时器实例相同的范围内触发。选项包括:
a) 使用 LifetimeScope.Transient
,尽管这可能会与其他服务发生冲突,例如它会受益于跨范围共享的实例,尤其是在传递实体时。
b) 在您的计时器中确定 DbContext 实例的范围,而不是依赖使用注入的 DbContext 的共享服务。
c) 使用 AsNoTracking()
进行计时器读取。这将确保从数据库中读取实体 returned。 (已通过 EF6 验证,在 EF Core 中应保持一致)这可能意味着在您的服务中引入类似默认参数的内容,以指示是否将 AsNoTracking()
附加到查询以确保重新读取。
d) 将查询基于投影而不是 returning 实体实例。例如,当您编写查询以使用 .Select()
或 .ProjectTo()
(Automapper) 时,这些查询将自动 return 当前数据库状态,避免跟踪实例中可能存在的陈旧数据。
我有一个计时器,每 10 秒计时一次。 计时器结束后,它将调用我的服务,然后获取数据 从我的服务并将其分配给我的 radzen table 然后 StateHasChanged 将 重新呈现页面并更新更改。
@using System.Timers;
Timer _timer;
protected override async Task OnInitializedAsync()
{
StartTimer();
}
private void StartTimer()
{
_timer = new System.Timers.Timer();
_timer.Interval = 10000; //every 10 seconds
_timer.Elapsed += DashboardTimerElapsed;
_timer.Start();
}
private async void DashboardTimerElapsed(Object source, ElapsedEventArgs e)
{
await FetchData();
}
private async Task FetchData()
{
dashboardData = await getDataService.GetDataAsync();
await InvokeAsync(StateHasChanged);
}
计时器已过且一切正常,我遇到的唯一问题是如果我的应用程序是 运行,我对数据库中的一个数据进行了更改,例如:更改值名称“shazam”到“沙赞”。在过去时,我的新数据应该拉下“shazamm”,但是当我查看 dashbardData 时,我可以看到它没有拉下“shazamm”,而是拉下“shazam”,我认为这是 dbcontext 的旧实例。 (顺便说一句,我的 dbcontext 是有范围的)-
services.AddDbContext<DbContext>(options => {
options.UseSqlServer(Configuration.GetConnectionString("DbContextURL"));
}, ServiceLifetime.Scoped);
任何人都可以看到我哪里错了并帮助我吗?谢谢!
计时器事件将在与计时器实例相同的范围内触发。选项包括:
a) 使用 LifetimeScope.Transient
,尽管这可能会与其他服务发生冲突,例如它会受益于跨范围共享的实例,尤其是在传递实体时。
b) 在您的计时器中确定 DbContext 实例的范围,而不是依赖使用注入的 DbContext 的共享服务。
c) 使用 AsNoTracking()
进行计时器读取。这将确保从数据库中读取实体 returned。 (已通过 EF6 验证,在 EF Core 中应保持一致)这可能意味着在您的服务中引入类似默认参数的内容,以指示是否将 AsNoTracking()
附加到查询以确保重新读取。
d) 将查询基于投影而不是 returning 实体实例。例如,当您编写查询以使用 .Select()
或 .ProjectTo()
(Automapper) 时,这些查询将自动 return 当前数据库状态,避免跟踪实例中可能存在的陈旧数据。