J'ai un modèle de domaine POCO qui est câblé jusqu'au cadre d'entité à l'aide de la nouvelle classe ObjectContext.
public class Product { public Product() { Photos = new Collection<Photo>(); } public int Id { get; set; } public string Name { get; set; } private Collection<Photo> Photos {get; set; } public IEnumerable<Photo> GetPhotos() { return Photos; } public void AddPhoto(Photo photo) { //Some biz logic //... Photos.Add(photo); } }
5 Réponses :
(excuses pour ma première brièveté de la première brièveté - je répondais de mon téléphone) P>
Vous pouvez construire votre collection via une requête LINQ sur une définition d'entité EF. Cependant, vous conservez la collection résultante en tant que membre de données interne à votre classe d'entreprise et exposez le Vous pouvez mettre en cache le Alternativement, si votre appelant fonctionnera toujours avec l'ensemble de l'entité complète, la classe code> Entityset Code> (de laquelle tous vos jeux d'EF hériteront) implémente Notez que si vous souhaitez que le chargement de la collection d'une entité EF soit défini en dehors de la portée de votre classe d'entreprise, vous pouvez créer un constructeur sur votre classe qui prend un ienumerable
asen-témoine () code> sur l'entité définie à la suite de la photo publique. p>
asenumerable () code> chaque fois que votre appelant demande la collection. Bien entendu, cela signifie que si l'utilisateur doit mettre à jour la collection via vos méthodes publiques, vous devrez peut-être vous rafraîchir le
iEnumerable code>. Cela pourrait poser un petit problème si l'appelant a également mis en cache le pointeur sur le précédent
ienumerable code>. P>
ienumerable
icollection code>. De cette façon, une fois que vous avez créé votre objet, la collection est scellée et exposée uniquement comme un
ienumerable code>. P>
Je ne vois pas comment appeler des œuvres asénumables dans ce cas? Pouvez-vous expliquer un peu plus?
Asenumerable () Code> aidera à rendre la collection vraiment immuable, car sans cela, un appelant peut toujours le faire:
(((collection
Asenumerable () suppose que la Collection a interprété par le moyen normal de construire des collections à partir d'EF - soit via une requête LINQ ou d'accéder directement à l'entité.
Notre couche de domaine est séparée de la couche de données. J'utilise le motif de référentiel pour passer des objets POCO de la couche de données à nos objets métier. Ce que vous suggère de suggérer est tout à fait possible que la logique de la base de données s'est engagée dans le modèle de domaine / économique, que certains pourraient dire n'est pas pur poco.
Je vois. Dans ce cas, je créerais l'objet POCO (photos dans votre exemple) avec un constructeur explicite qui prend une ICOLLection. De cette façon, votre couche de données sera responsable de l'instanciation de l'objet POCO et de le charger avec les données d'EF, tandis que votre objet POCO exposera toujours les données comme une iNeumable. Aucun client de l'objet métier ne sera capable de mettre à jour la collection directement. Je vais mettre à jour ma réponse avec cette suggestion.
Qu'en est-il de Readonlycollection
@Isaac Abraham - Readonlycollection
iEnumerable
Pourquoi ne pas essayer les propriétés suivantes et laissez des propriétés d'utilisation?
private ICollection<Photo> photos{get; set;} public IEnumerable<Photo> Photos { get {return (IEnumberable<Photo>)photos;} }
Anton, cela m'aiderait à comprendre votre problème plus si vous pouvez expliquer pourquoi vous ne voulez pas que les développeurs accèdent à la méthode de votre collection. Est-ce parce que la liste est strictement lecture seule, ou est-ce parce que vous souhaitez exécuter une logique commerciale personnalisée lorsqu'une nouvelle entité est ajoutée?
De toute façon ... Je vais supposer que vous essayez de faire ce dernier (c.-à-d. Exécuter la logique commerciale personnalisée lorsque la collection est modifiée). J'ai fait une solution similaire sur un projet de mien et l'idée est la suivante: p>
Le modèle TT qui produit des POCOS dans EF4 crée toutes les collections en tant que listes de trackablecollection. Cette classe a un événement appelé «Collectionchangted» que vous pouvez vous abonner à vos modifications apportées à votre collection. P>
afin que vous puissiez faire quelque chose comme suit: p>
public class Product { public Product() { Photos.CollectionChanged += ListCollectionChanged; } public int Id { get; set; } public string Name { get; set; } public TrackableCollection<Photo> Photos { get { // default code generated by EF4 TT } set { // default code generated by EF4 TT } } private void ListCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { // A new item has been added to collection case NotifyCollectionChangedAction.Add: { T newItem = (T) e.NewItems[0]; // Run custom business logic } break; // An existing item has been removed case NotifyCollectionChangedAction.Remove: { T oldItem = (T) e.OldItems[0]; // Run custom business logic } break; } } }
La manière de le faire est d'avoir une propriété virtuelle protégée qui est mappée dans votre modèle et une propriété publique qui renvoie un iénumérable.
public class Product { public Product() { PhotoCollection = new Collcation<Photo>(); } public int Id { get; set; } public string Name { get; set; } protected virtual ICollection<Photo> PhotoCollection {get; set; } public IEnumerable<Photo> Photos { get { return PhotoCollection ; } } public void AddPhoto(Photo photo) { //Some biz logic //... PhotoCollection .Add(photo); } }
Le problème avec ceci est: photos code> ne fonctionnera pas avec LINQ vers des entités qui laisse potentiellement potentiel pour de nombreux autres hits dans la base de données en nécessitant l'utilisation de
Tolist () code> E.G.
produit.photos.toliste (). Où (p => .... code>
peu en retard à la fête, mais c'est ce que sont les objets observables. Permettez à la structure de données de faire ce qu'il fait le mieux. Utilisez Observablecollection comme type de champ Si vous ne souhaitez pas créer votre propre collection qui fait ce dont vous avez besoin et exposez le type d'icollection régulier de votre propriété. Vous pouvez exécuter n'importe quelle logique de l'entité mère dont vous avez besoin lorsque les entités associées de la collecte changent via l'événement de collectionChanged. Si vous devez activer ou désactiver de manière sélective des modifications, il est suffisamment facile d'étendre un type de collecte existant ou d'écrire une collection de proxy qui permet à un appel à une méthode pour basculer l'assurance de la collection (Isupportunitialize peut être utilisé à bon effet pour représenter cette capacité BTW ). p>
J'aimerais pouvoir trouver une réponse à cela!