LINQ to SQL et le modèle de référentiel
J'ai l'impression de courir en cercles. Je n'arrive pas à me décider sur ce que la droite modèle de référentiel est à l'aide de LINQ to SQL. Si vous êtes familier avec Rob Conery de l' MVC Vitrine vous verrez que sa mise en œuvre enveloppe le LINQ modèles générés avec une autre classe et traite le LINQ généré simplement comme un objet de transfert de données (DTO). Il ressemble à quelque chose comme ceci:
//Custom wrapper class.
namespace Data
{
public class Customer
{
public int Id {get;set;}
public string Name {get;set;}
public IList<Address> Addresses {get;set;}
}
}
//Linq-Generated Class - severly abbreviated
namespace SqlRepository
{
public class Customer
{
public int Id {get;set;}
public string Name {get;set;}
public EntitySet<Address> {get;set;}
}
}
//Customer Repository
namespace SqlRepository
{
public class UserRepository : IUserRepository
{
private _db = new DB(); //This is the Linq-To-Sql datacontext
public IQueryable GetCusomters()
{
return
from c in _db.Customers
select new Customer //This is the wrapper class not the gen'd one
{
Id = c.Id,
Name = c.Name,
Addresses = new LazyList(c.Addresses)
};
}
Quel est l'avantage de cette façon de faire (à l'aide d'une classe wrapper), par opposition à la façon dont Mike Hadlow suggère dans À l'aide de la IRepository modèle avec LINQ to SQL dans sa version de IRepository<T>, où il retourne juste la DTO des objets du référentiel?
Où la logique métier être appliquées et contrôlées? Est-ce dans un autre calque, tous ensemble, appelé par le référentiel sur enregistrer/mettre à jour, ou est-il intégré à la classe wrapper?
Vous devez vous connecter pour publier un commentaire.
Le truc, c'est cela, LINQ to SQL n'est pas un vrai La Relation D'Objet Mappeur (ORM), c'est une couche d'accès aux données du générateur. Vous pouvez faire un ORM par aller en profondeur par la main de l'édition de fichiers XML et de jouer avec SqlMetal et autres joyeusetés, mais là où elle brille comme une DAL.
L'idée derrière un ORM est-ce. Vous avez votre base de données SQL, et votre domaine d'objets. La conception d'une base de données correctement, vous allez faire des choses (comme la normalisation) qui, logiquement, ne se traduisent pas dans un plan bien conçu modèle objet, et vice-versa. Ceci est appelé "adaptation d'Impédance", le rôle d'un ORM est de faire face à cette situation dans un endroit propre, efficace, et efficace. Le moins douloureux interaction de base de données est presque secondaire chose.
L'idée derrière un référentiel, c'est qu'il est un condensé de tous persistance de la logique et des dépendances sur l'infrastructure du reste de votre application. Lorsque votre application a besoin d'un Client de l'objet, il ne devrait pas avoir pour savoir si elle est à venir à partir de SQL Server, MySQL, un fichier XML, ou ASP.NET l'Adhésion. Une fois que vous avez que de couplage, toutes les modifications que vous apportez à votre persistance de l'histoire n'ont aucun effet sur le reste de votre application.
Avec cela à l'esprit, il devient de plus en plus clair pourquoi il a fait ce qu'il a fait. LINQ to SQL est utilisé pour générer le DAL, mais la seule chose qui doit être connu sur le DAL est le dépôt, donc la traduction est faite à son domaine d'objets. De cette façon, il peut refactoriser son modèle de domaine sans se soucier de sa persistance histoire, et il peut refactoriser sa base de données sans se soucier de l'ondulation des effets par le biais de son application. Il pourrait aussi commencer à coder sur une logique d'entreprise avant de décider sur des questions comme ce ORM à utiliser, ou même de l'endroit où stocker ses données.
S'il était l'utilisation d'une ORM (comme NHibernate), que la cartographie code est traité ailleurs (que ce soit en XML ou d'amorçage classes). Je pense que LINQ to SQL (et Prive open source DAL, SubSonic) sont de grands projets, mais plus conçu pour les petits, deux applications de la couche où quelque chose comme le modèle de référentiel est exagéré. La devanture est également une bonne illustration de pourquoi la complexité supplémentaire de NHibernate peut être important. Il aurait pu lui-même sauvé beaucoup de code en allant avec quelque chose de construit pour traiter ce genre de scénario, plutôt que de le faire manuellement.
Cela dépend d'où la Otd sont définis et comment vous voulez le tester. Si vous utilisez des DBML, puis LINQ to SQL veut générer les objets de données dans la couche de données. Alors que LINQ to SQL prend en charge persistance de l'ignorance, il ne veut pas sortir de sa façon de faire, c'est facile. Entity Framework ne le supporte pas du tout.
Cela signifie que dans le modèle standard, votre couche de données est la définition de l'ensemble du domaine des entités, ce qui est difficile si vous voulez tester l'interface utilisateur/couches de gestion d'un véritable isolement à partir de la couche de données.
Une approche pragmatique pourrait être d'utiliser les données, les définitions d'objets de la couche de données dans les tests unitaires, mais pas les données de contexte (c'est à dire cacher les données de contexte derrière le référentiel de l'interface, mais d'exposer les types d'entité) - mais c'est pour brouiller les cartes un peu, et signifie que votre INTERFACE, etc. besoin d'fortement de référence de la couche de données. Mais si vous pensez à cela comme un "modèle de domaine de la couche qui se trouve également contenir un référentiel de mise en œuvre que l'on peut ou ne peut pas être à l'aide", vous pouvez le justifier.
Garder complètement séparée de domaine entités qui rend les tests unitaires et l'inversion de contrôle (Cio) de plus "pur", mais augmente la quantité de code (donc à double tranchant).
Sont les objets générés sérialisable? J'ai eu l'impression qu'ils ne l'étaient pas. C'est juste une affaire de l'isolement comme Marc Gravier dit ci-dessus.
Que si vous passez le référentiel et d'avoir une base de données MySQL, Oracle, XML, Web service, ou quel que soit le fournisseur de données (Référentiel)? Vous serait liée à l'LINQ to SQL assemblée pour faire référence à des entités, à droite? Ce qui, bien sûr, vous ne voulez pas.