我有一个WPF
项目,MVVM
带有EF6
数据集,我正在寻找实现回滚所有更改的方法。
以下代码显示了ViewModel如何加载数据:
protected async override void GetData()
{
ThrobberVisible = Visibility.Visible;
ObservableCollection<MobileDeviceRequestVM> _requests = new ObservableCollection<MobileDeviceRequestVM>();
var requests = await (from c in dbContext.MobileDeviceRequests
orderby c.RequestDate
select c)
.ToListAsync();
foreach (MobileDeviceRequest req in requests)
{
_requests.Add(new MobileDeviceRequestVM { IsNew = false, TheEntity = req });
}
MobileDeviceRequests = _requests;
RaisePropertyChanged("MobileDeviceRequests");
ThrobberVisible = Visibility.Collapsed;
}
以下代码显示ViewModel
如何回滚任何更改:
protected override void RollbackData()
{
var changedEntries = dbContext.ChangeTracker.Entries()
.Where(x => x.State != EntityState.Unchanged).ToList();
foreach (var entry in changedEntries)
{
switch (entry.State)
{
case EntityState.Modified:
entry.CurrentValues.SetValues(entry.OriginalValues);
entry.State = EntityState.Unchanged;
break;
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Deleted:
entry.State = EntityState.Unchanged;
break;
}
}
//Somewhere in here the OC: MobileDeviceRequests needs to get refreshed
//with the context as items may have been added and/or deleted
RaisePropertyChanged("MobileDeviceRequests");
}
以下代码显示了ViewModel
如何刷新数据,根据某些内容是否发生了变化,这些数据可能会也可能不会回滚数据:
protected virtual void RefreshData()
{
GetData();
}
以下内容创建了新的上下文
protected virtual void ReloadData()
{
dbContext= new BAContext();
GetData();
}
我想知道的是:
回滚
VS
清爽
vs
重装
他们似乎都做了同样的事情,ReloadData()更贵。
我想我要问的是,如果刷新了重新查询并填充了OC,那么回滚是否有任何意义。如果有,那么你将如何重新填充OC并且它与刷新有什么不同?
答案 0 :(得分:2)
上述方法并不相同。
执行LINQ to Entities跟踪查询时,EF将重新查询数据库,但随后会考虑返回实体的当前更改跟踪器状态,并返回本地实体数据而不是实际数据。该概念类似于旧版RefreshMode.ClientWins方法的ObjectContext.Refresh选项。
刷新的最终效果是它最终会带来新数据(通过不同的上下文实例或其他进程/用户添加到数据库中)。但目前的修改将继续有效。
所以IMO你的选项只有两个 - 回滚当前或使用新的上下文。实现它的方式,回滚方法似乎工作,但实体查询仍然不会应用在上下文实例之外进行的更改。但这适用于长期生存环境中的跟踪实体查询,因此可能不会被视为缺陷。
您选择的两个中哪一个取决于您的要求。但唯一有保证的新方法就是使用新的上下文实例。