保持 IEnumerable 和 ObservableCollection 同步
Keeping an IEnumerable and an ObservableCollection in sync
简短版本:
我有两个 collections:一个 IEnumerable
和一个 ObservableCollection
。我需要一种方法让它们保持同步。这意味着,如果在一个中添加、删除或更新了任何项目,则该项目且仅该项目将在另一个中自动添加、删除或更新。如何做到这一点?
长版:
我正在使用 Entity Framework
和 WPF
。由于我使用 MVVM
实现存储库模式,ViewModel
仅获得 IEnumerable
个实体。我需要将它们转换为 ObservableCollection
而不会失去 Entity Framework
.
提供的 change tracking
的能力
我在网上寻找解决方案,但没有成功。有什么正确的方法吗?
跟踪 ObservableCollection
变化很简单; class - 更具体地说,它实现的接口 - 有一个你可以订阅的 CollectionChanged
事件。有关此事件及其事件参数的信息,请参阅 MSDN。
根据定义,IEnumerable
只是一个可以枚举的集合。它没有等效的 "change" 概念,因为除了遍历 it/filtering 它之外没有任何业务。如果您坚持使用 IEnumerable
,那么更改通知的责任必须向上移动到维护集合的任何级别。
一般情况下,问题没有通用的解决办法。
话虽如此。您没有使用 IEnumerable
。您正在使用 DbSet<T>
,它公开了 public ObservableCollection<T> Local { get; }
。解决方案。不要同步两个集合。只需使用正确的集合开始。
编辑问题:
我会重构您的代码,使 "Repository" 成为集合。
public class FooRepository
: ICollection<Foo>
, INotifyCollectionChanged
{
private BarDbContext _context;
public FooRepository()
{
_context = new BarDbContext();
_context.Foos.Local.CollectionChanged += (o, e) => CollectionChanged(this, e);
}
//Delegate ICollection to _context.Foos.Local
public Foo this[int index] { get { return _context.Foos.Local[index]; } }
public Task Load(Expression<Foo, bool> predicate)
{
return _context.Foos.Where(predicate).LoadAsync();
}
}
简短版本:
我有两个 collections:一个 IEnumerable
和一个 ObservableCollection
。我需要一种方法让它们保持同步。这意味着,如果在一个中添加、删除或更新了任何项目,则该项目且仅该项目将在另一个中自动添加、删除或更新。如何做到这一点?
长版:
我正在使用 Entity Framework
和 WPF
。由于我使用 MVVM
实现存储库模式,ViewModel
仅获得 IEnumerable
个实体。我需要将它们转换为 ObservableCollection
而不会失去 Entity Framework
.
change tracking
的能力
我在网上寻找解决方案,但没有成功。有什么正确的方法吗?
跟踪 ObservableCollection
变化很简单; class - 更具体地说,它实现的接口 - 有一个你可以订阅的 CollectionChanged
事件。有关此事件及其事件参数的信息,请参阅 MSDN。
根据定义,IEnumerable
只是一个可以枚举的集合。它没有等效的 "change" 概念,因为除了遍历 it/filtering 它之外没有任何业务。如果您坚持使用 IEnumerable
,那么更改通知的责任必须向上移动到维护集合的任何级别。
一般情况下,问题没有通用的解决办法。
话虽如此。您没有使用 IEnumerable
。您正在使用 DbSet<T>
,它公开了 public ObservableCollection<T> Local { get; }
。解决方案。不要同步两个集合。只需使用正确的集合开始。
编辑问题:
我会重构您的代码,使 "Repository" 成为集合。
public class FooRepository
: ICollection<Foo>
, INotifyCollectionChanged
{
private BarDbContext _context;
public FooRepository()
{
_context = new BarDbContext();
_context.Foos.Local.CollectionChanged += (o, e) => CollectionChanged(this, e);
}
//Delegate ICollection to _context.Foos.Local
public Foo this[int index] { get { return _context.Foos.Local[index]; } }
public Task Load(Expression<Foo, bool> predicate)
{
return _context.Foos.Where(predicate).LoadAsync();
}
}