Je pense que c'est une question assez simple mais je suis toujours incapable de trouver une meilleure solution pour cela. Donc, après avoir fait des recherches sur ce sujet, j'ai pensé à poser cette question ici pour avoir une opinion d'expert.Comment faire pour activer ObservableCollection en tant que collection wrapper pour suivre les modifications?
Fondamentalement, je travaille sur l'application WPF et j'ai défini GenericObserableCollection<T>
implémentant ObservableCollection<T>
et la plupart des collections l'implémentent pour avoir une approche standard dans tout le projet.
[Serializable]
[CollectionDataContract]
public class GenericObservableCollection<T> : ObservableCollection<T>
{
public GenericObservableCollection() { }
public GenericObservableCollection(IEnumerable<T> collection)
: base(collection) { }
}
[Serializable]
[CollectionDataContract]
public class GenericRuleCollection : GenericObservableCollection<IRule>
{
public GenericRuleCollection() { }
public GenericRuleCollection(IEnumerable<IRule> collection)
: base(collection) { }
}
Dans un premier temps, il était bon, mais plus tard, quand Entity Framework est entré en l'image que je devais changer la conception de domaine de façon drastique, car EF nécessite d'exposer ICollection<T>
pour la cartographie. À ce moment-là, j'étais confus en gardant le minimum de changements et je m'adaptais à EF parce que j'étais nouveau. Plus tard, après avoir fait des recherches, je suis tombé sur quelques bons articles traitant ce scénario.
- Exposing Private Collection Properties to Entity Framework
- Mapping but not exposing ICollections in Entity Framework
I a appliqué la même approche dans mon domaine d'application créant ChildrenStorage
pour tenir ICollection<GenericRule>
comme une exigence pour EF.
Maintenant, je suis à la recherche d'une approche intelligente et élégante pour garder mes deux collections, c'est-à-dire ChildrenStorage
et Children
en synchronisation lorsque des éléments sont ajoutés et/ou supprimés. Puisque la collection Children
est celle qui sera modifiée via l'interface utilisateur, je veux garder une trace de toutes les modifications apportées à Children
et souhaite synchroniser ChildrenStorage
.
[Serializable]
[DataContract]
public abstract class GenericContainerRule : GenericRule
{
protected GenericContainerRule() : this(null)
{
ChildrenStorage = new List<GenericRule>();
}
protected GenericContainerRule(string name) : base(name)
{
ChildrenStorage = new List<GenericRule>();
}
public void AddChild(IRule rule)
{
ChildrenStorage.Add(rule as GenericRule);
_children = new GenericRuleCollection(ChildrenStorage);
OnPropertyChanged(nameof(Children));
}
public class OrMappings
{
public static Expression<Func<GenericContainerRule, ICollection<GenericRule>>> ChildrenAccessor = t => t.ChildrenStorage;
}
[DataMember]
protected ICollection<GenericRule> ChildrenStorage { get; set; }
private GenericRuleCollection _children;
public GenericRuleCollection Children => _children ?? (_children = new GenericRuleCollection(ChildrenStorage));
private GenericRuleCollection _children;
[DataMember]
public virtual GenericRuleCollection Children
{
get { return _children; }
private set { SetProperty(ref _children, value); }
}
}
Mais votre GenericObservableCollection implémente déjà ICollection, pourquoi vous avez besoin d'avoir une autre collection? –
Evk
Je n'ai pas besoin d'une autre collection, je veux juste que toutes les modifications de 'ChildrenStorage' soient reflétées automatiquement dans' Children' –
Idéalement, vous ne devriez pas mélanger votre modèle de données EntityFramework avec votre viewmodel (ou même votre "vrai" modèle dépendant de loin vous voulez séparer les choses). Le modèle de données est vraiment destiné uniquement à l'accès aux données de la base de données, et ne sera pas utilisé lors de l'interaction avec des choses comme les règles métier. Vous utiliserez généralement une forme de mappeur automatique pour déplacer des données entre le modèle EF et votre modèle d'entreprise. –