2017-03-15 3 views
0

Kurzfassung Keeping:ein IEnumerable und eine ObservableCollection synchron

Ich habe zwei Sammlungen: eine IEnumerable und eine ObservableCollection. Ich brauche einen Weg, um sie synchron zu halten. Das heißt, wenn ein Artikel in einem Artikel hinzugefügt, gelöscht oder aktualisiert wird, wird dieser Artikel und nur dieser Artikel automatisch hinzugefügt, gelöscht oder aktualisiert. Wie kann das gemacht werden?

Lange Version: Ich verwende Entity Framework mit WPF. Da ich Repository-Muster mit MVVM implementiere, erhält der ViewModel nur IEnumerable von Entitäten. Ich brauche sie in ObservableCollection umgewandelt werden, ohne die Fähigkeit change tracking von Entity Framework zur Verfügung gestellt zu verlieren.

Ich habe das Netz nach der Lösung gesucht, aber vergeblich. Gibt es einen Weg, es richtig zu machen?

Antwort

3

Im allgemeinen Fall gibt es keine allgemeine Lösung für das Problem.

Das sagte. Sie verwenden nicht IEnumerable. Sie verwenden DbSet<T>, wodurch public ObservableCollection<T> Local { get; } verfügbar gemacht wird. Lösung. Synchronisieren Sie nicht zwei Sammlungen. Verwenden Sie einfach die richtige Sammlung.

EDIT re Frage:

Ich würde Ihren Code Refactoring, so dass das "Repository" die Collection enthalten ist.

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(); 
    } 
} 
+0

Eine naive Frage hier: Nehmen wir an, ich tue dies in meinem Repository: 'IEnumerable Findwhere (Ausdruck > Prädikat) {return context.Set () .Where (Prädikat) .ToList(); } ' Mit anderen Worten, ich bin eifrig laden. Wenn ich Local verwenden möchte, soll ich explizit Load() laden? –

+0

Ihre Bearbeitung hat vielleicht funktioniert, wenn ich nur eine Methode in meinem Repository hatte. Aber hier ist nur ein Teil davon. Wie soll ich damit umgehen? 'öffentliche T FetchByPrimaryKey (Objekt Primärschlüssel) { Rückkehr _ctx.Set () .Find (Primärschlüssel); } public IEnumerable Findwhere (Expression > Prädikat) { return _ctx.Set () .Where (Prädikat).Auflisten(); } public T FirstOrDefault (Expression > Prädikat) { return _ctx.Set () .Where (Prädikat) .FirstOrDefault(); } ' –

2

Den Überblick über ObservableCollection Änderungen zu behalten ist trivial; Die Klasse - genauer gesagt die Schnittstelle, die sie implementiert - hat ein CollectionChanged Ereignis, das Sie abonnieren können. Informationen zu diesem Event und seinen Event-Argumenten finden Sie unter MSDN.

Eine IEnumerable, per Definition, ist nur eine Sammlung, die Sie aufzählen können. Es hat kein äquivalentes "Änderungs" -Konzept, weil es nichts anderes damit zu tun hat, als es zu durchlaufen/zu filtern. Wenn Sie mit IEnumerable festgefahren sind, dann muss die Verantwortung für Änderungsbenachrichtigungen auf eine Ebene verschoben werden, die die Sammlung verwaltet.

+1

Obwohl alles, was Sie geschrieben haben, korrekt ist. Ein sorgfältigeres Lesen der Frage zeigt, dass "IEnumerable" tatsächlich EntityFramework ist. In diesem Fall ist die Lösung einfach. Sie verwenden einfach die Eigenschaft 'DbSet .Local'. – Aron

+0

Ich sehe! Danke für die Klarstellung. –