Question

J'espère que le titre et le texte suivant sont claires, je ne suis pas très familier avec les termes corrects alors s'il vous plaît me corriger si je reçois quelque chose de mal. J'utilise LINQ ORM pour la première fois et je me demande comment aborder les points suivants.

Dire que j'ai deux tables DB:

User
----
Id
Name


Phone
-----
Id
UserId
Model

Le générateur de code Linq produit un tas de classes d'entités.

Je puis écrire mes propres classes et interfaces qui enveloppent ces classes Linq:

class DatabaseUser : IUser
{
    public DatabaseUser(User user)
    {
        _user = user;
    }

    public Guid Id 
    {
        get { return _user.Id; } 
    }

    ... etc
}

so far so good.

Maintenant, il est assez facile de trouver un utilisateur des téléphones de Phones.Where(p => p.User = user) mais sûrement comsumers de l'API ne devrait pas avoir besoin d'écrire leurs propres requêtes LINQ pour obtenir à des données, donc je devrais envelopper cette requête dans une fonction ou propriété quelque part.

La question est donc, dans cet exemple, voulez-vous ajouter une propriété Téléphones à IUser ou non?

En d'autres termes, si mon interface être spécifiquement modéliser mes objets de base de données (auquel cas les téléphones ne font pas partie de IUser), ou sont-ils en fait simplement fournir un ensemble de fonctions et les propriétés qui sont conceptuellement associées à un utilisateur (en auquel cas il fait)?

Il semble inconvénients à deux points de vue, mais je me demande s'il y a une approche standard du problème. Ou tout simplement des mots généraux de la sagesse que vous pourriez partager.

Ma première pensée était d'utiliser des méthodes d'extension, mais en fait cela ne fonctionne pas dans ce cas.

Était-ce utile?

La solution

J'ai eu des expériences terribles essayant d'entités abstraites de LinqToSql derrière des interfaces. Il était tout à l'heure, mais de mémoire, le principal problème est que ça casse totalement les associations. Par exemple, si vous avez un Customer -> relation Order, vous finissez par l'exposer comme ICustomer, avec une collection de IOrders, ce qui signifie que Customer doit faire une cartographie maladroite de jeter sa collection interne d'objets Order comme IOrders <. / p>

Ensuite, vous devez supposer que lorsqu'un IOrder est transmis en retour, que nous pouvons jeter un Order. Dans le cas contraire LinqToSql ne peut pas traiter avec elle, mais que les défaites le point d'avoir l'interface il en premier lieu.

Je recommande fortement que vous ne pas essayer et abstraire les classes d'entités trop, LinqToSql ne fait pas mettre une vraie magie en eux, les poignées DataContext leur cycle de vie de la persistance, de sorte qu'ils restent testable.

Les aspects que je rechercherais de se cacher derrière une interface serait les interactions avec DataContext, par exemple en utilisant des classes de style référentiel:

public interface IPhoneRepository 
{
    IEnumerable<Phone> GetPhonesForUser(User user);
}

public class L2SPhoneRepository : IPhoneRepository
{
    private readonly MyDataContext context;

    public L2SPhoneRepository(MyDataContext context)
    {
        this.context = context;
    }

    public IEnumerable<Phone> GetPhonesForUser(User user)
    {
        return context.Phones.Where(p => p.User == user);
    }
}

Autres conseils

Votre interface doit modéliser la façon dont vous souhaitez les objets à utiliser. Puisque vous essayez de faire abstraction, le consommateur ne devrait pas avoir à interroger la base de données. Que vous fassiez une propriété, ou un appel de fonction distincte (c.-à-GetPhones ()), est entièrement à vous. Puisque vous êtes complètement envelopper les choses, vous devrez faire des choix sur la profondeur / paresseusement que vous voulez charger vos objets.

Vous devez ajouter propriété Téléphones à IUser et rendre annulable, donc pour un utilisateur qui n'ont pas de téléphone, il sera nulle.

Puisque vous ne voulez pas que les consommateurs de l'API pour écrire des requêtes, que vous devez mettre en œuvre des fonctions comme GetUser () .. etc.

Voici une belle liste d'application de l'article vers n-tier en Asp.net

http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=416

J'ai tendance à considérer la Linq2Sql des choses liées à être un détail de mise en œuvre du code d'accès aux données et, comme la structure réelle de la base de données, ne doit pas nécessairement être exposés à d'autres parties du système.

Si votre API va être consommée par d'autres personnes, il doit être cohérent et facile à utiliser et non encombré par des choses que le consommateur n'a pas besoin de connaître. Si je traite avec les utilisateurs et leurs téléphones Je ne veux pas vraiment savoir sur DataContexts ou (ugh) DataSets.

En outre, en gardant la majeure partie de votre code ignorant les L2S et base de données, vous aurez un test plus facile, des changements de schéma (oh, maintenant la table utilisateur doit conserver un historique de toutes les modifications apportées) ou même changer l'ORM complètement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top