2010-04-09 5 views
3

J'utilise un modèle de référentiel avec linq to sql, j'utilise une classe de référentiel par table. Je veux savoir, ce que je fais au bon/moyen standard,Linq to sql Modèle de référentiel, quelques questions

ContactRepository

Contact GetByID() 
    Contact GetAll() 

COntactTagRepository

List<ContactTag> Get(long contactID) 
List<ContactTag> GetAll() 
List<ContactTagDetail> GetAllDetails() 

class ContactTagDetail 
{ 
    public Contact Contact {get;set;} 
    public ContactTag COntactTag {get;set;} 
} 

Quand je besoin d'un contact que j'appelle méthode contactrepository, même pour contacttag

mais quand j'ai besoin de contact et de balises ensemble, j'appelle GetDetais() dans le dépôt ContactTag et ne renvoie pas l'entité COntactTag généré par l'orm insta son retour ContactTagDetail entité à la fois COntact et COntactTag généré par l'orm, je sais que je peux simplement appeler GetAll dans le référentiel COntactTag et peut accéder à Contact.ContactTag mais comme linq à sql il n'y aura pas d'option à la charge différée au niveau de la requête, de sorte que chaque fois que je besoin d'une entité avec une entité apparentée je crée une classe de projection

un autre doute est là où je vraiment besoin de droite la méthode que je peux le faire dans les deux contacts & ContactTag repostitory comme dans le référentiel de contact GetALlWithTags () ou quelque chose mais je le fais dans le dépôt COntactTag

Quelles sont vos suggestions?

Répondre

5

Je n'ai pas le temps d'entrer dans les détails, mais fondamentalement, je n'ai pas de relation bi-univoque entre les tables et vos dépôts. J'ai fait cette erreur, et ça ne marche pas. Au lieu de cela, demandez à votre référentiel de contenir toutes les tables liées conceptuellement. Dans votre cas, il suffit d'avoir un référentiel Contact qui gère à la fois les Contacts et les ContactTags (et toutes les autres tables connexes). Il n'y a pas de règle sur ce que signifie «lié», vous seul pouvez décider - mais régissez votre décision en fonction de votre compréhension de la façon dont les éléments de votre demande sont naturellement regroupés.

ont également une lecture de ces deux fils sur SO qui traitent d'une question similaire:

Multiple or Single Repositories with LINQ et How to use the repository pattern correctly?

+0

son bien, mais quand je suis dépôt avec de nombreuses entités connexes où je vais écrire l'insertion/suppression des méthodes etc, – MindlessProgrammer

+0

vous pourriez mettez-les tous dans un même répertoire, à condition qu'ils soient liés comme une «unité de travail». –

-1

Je crois que vous êtes sur la bonne voie. Un problème que vous rencontrerez avec linq to sql est le mappage un à un avec des tables. Vous êtes donc obligé de vous exposer à plusieurs tables de relation. La manière dont j'ai contourné ceci est d'utiliser une couche de données qui a accès à linq to sql mais qui mappe tout à des objets POCO avant de renvoyer l'appel. Fondamentalement, je suis en train de mapper l'image de l'objet linq vers un objet POCO Image. (Je sais que ce genre de désordre, mais il le meilleur exemple que j'ai sous la main.)

Pour obtenir l'effet de la charge différée vous reviendriez un IQueryable < T objet >. Cela vous permettra de suspendre l'exécution de la requête jusqu'à ce que vous en ayez besoin.

également pour les objets avec collection dépendants à eux, je trouve cette grande classe d'aide: LazyList il permet un chargement paresseux (exécution différée) des collections via IQueryable <T>

La plupart de ce que je sais est de lire Rob Connerys Blog MVC Store Front.

Lire son article de blog et télécharger le projet Avant-vente Je pense qu'il répondra à beaucoup de vos questions. Si vous n'utilisez pas asp.net MVC juste regarder par-dessus sa couche d'accès aux données devrait être une aide énorme.

Hope qui aide

+1

Rob Connery pas Roby Cory –

+0

Oups Merci Je mettrai à jour mon entrée – Anthony

+0

-1 Ne pas exposer que leaké 'IQueryable '. – jgauffin

1

Ce n'est pas le modèle référentiel. Le modèle de référentiel crée essentiellement un objet qui résout la persistance en agissant (conceptuellement) en tant que collection de tous les objets d'un certain type dans le domaine.

Par conséquent, un référentiel de contact pourrait fonctionner quelque chose comme ceci:

IContacts contacts = GetContactRepository(); 
using(var uow = UnitOfWork.Create()) { 
    var contact1 = contacts.Get(new FindByNameSpecification("Fred")); 
    contact1.LastName = "Rubble"; 
    var contact2 = new Contact("Barney", "Flistone"); 
    contacts.Add(contact2); 
    // both contact1 and contact 2 are implicitly saved at the end of the unit of work 
} 

un peu plus lâche définition de la façon dont le dépôt devrait fonctionner pourrait être quelque chose comme ceci:

IContactRepository contacts = GetContactRepository(); 
using(var uow = UnitOfWork.Create()) { 
    var contact1 = contacts.GetByName("Fred"); 
    contact1.LastName = "Rubble"; 
    contacts.Save(contact1); 
    var contact2 = new Contact("Barney", "Flistone"); 
    contacts.Save(contact2); 
} //The save is explicit but the commit is implicit 

Qu'est-ce que vous avez est un table data gateway.

Le problème est que vous créez une passerelle pour chaque table. Je recommanderais contre cela.

Le marquage fait-il partie de votre domaine de contacts ou non? Si c'est le cas, vous devriez avoir les propriétés

public class Contact { 
    public IEnumerable<Tag> Tags { get; } 
    public void TagWith(Tag tag) { .... } 
    public void UnTag(Tag tag) { ... } 
} 

En outre, demandez-vous vous jamais ajouter un tag qui n'a aucun contact en vertu de cela? Si non, alors il devient encore plus facile - vous n'avez pas besoin d'une passerelle pour gérer les balises du tout, laissez votre objet Contact manipuler

public interface IContactRepository { 
    IEnumerable<Contact> GetAll(); // returns Contacts along with their tags 
    void Save(Contact); // saves Contact along with any tags 
} 

Par ailleurs, si le marquage ne fait pas partie de votre domaine (comme dans ce est une préoccupation d'application), vous devriez avoir un service distinct, probablement même dans un projet distinct

public interface IAssociateTags { 
    IEnumerable<Tag> GetTagFor(Contact contact); 
    void TagContact(Contact contact, Tag tag); 
    void UnTagContact(Contact contact, Tag tag); 
}