7
votes

Quelle stratégie DAL utilisez-vous ou suggérez-vous?

Ma situation est que je fous essentiellement. J'ai hérité de ma base de code d'il y a environ 1,5 ans lorsque j'ai pris cette position et plutôt que de réinventer la roue, même si je sais maintenant que je devrais avoir, j'ai gardé le Dal dans la même structure que le développeur précédent.

Il existe essentiellement un fichier (maintenant à 15k lignes de code) qui se situe entre une bande de DAO qui utilise des jeux de données et des tableaux de table pour récupérer des données. Mes fichiers XSD ont grandi à une telle taille qu'elles provoquent R # sur Crash Visual Studio chaque fois qu'il s'ouvre et que la classe intermédiaire qui est maintenant de 15 000 lignes prend également pour toujours pour analyser. Sans parler de cela est moche, cela fonctionne mais pas bien et est un cauchemar absolu à déboguer.

Ce que j'ai essayé jusqu'à présent, passe à NHibernate. NHibernate est une grande bibliothèque, mais malheureusement, il n'était pas suffisable de travailler avec ma demande, de ce que dit le développeur principal (Fabio Maulo), il est à peu près une combinaison de mes exigences de l'application et des restrictions sur NHibernate lors de l'utilisation de l'identité en tant que base de données. Stratégie PK.

Alors maintenant, je suis de retour pour concevoir essentiellement mon propre dal. Je regarde quelques modèles différents pour cela, mais je voudrais obtenir vos stratégies de conception dal. Il y a tellement de façons et des raisons de mettre en œuvre un DAL de manière particulière, donc si vous pouviez expliquer votre stratégie et pourquoi il était le mieux adapté à vous, je l'apprécierais grandement.

Merci d'avance!

EDIT: Permettez-moi d'expliquer pourquoi NHibernate n'a pas fonctionné depuis que cela semble être la réponse immédiate. Mes utilisateurs créent un «travail» qui est en fait une représentation transitoire de ma classe d'emploi. Dans ce travail, ils lui donneront une ou une liste de facteurs de poids qui sont également transitoires au moment de la création. Enfin, ils fournissent une liste de détails d'emploi qui leur ont associé un facteur de poids particulier. Parce que, dans la base de données, des facteurs de poids sont uniques lorsque je vais persister le travail et que cela se cascade au facteur de poids, il meurt quand il trouve un facteur de poids en double. J'ai essayé de courir un chèque avant d'assigner le facteur de poids au détail (que je ne voulais pas faire parce que je ne veux pas les appels supplémentaires à la DB), mais appelant CreateCreCiteria en NH provoque également une rinçage de la session, selon Fabio, qui détruit mon cache et tue ainsi la représentation en pleine mémoire du travail. Les gens sur la liste de diffusion NH ont déclaré que je devrais passer à GUID, mais ce n'est pas une option réalisable car le processus de conversion serait un cauchemar.


4 commentaires

Quels problèmes avez-vous avec NHibernate? Je l'utilise avec l'identité PKS tout le temps sans problème.


HMM, peut-être qu'il utilise des sessions de longue date (session par modèle de transaction d'entreprise) et dans une telle approche, l'utilisation de l'identité est découragée, car elle enfreint votre unité de travail (il doit affleurer directement après avoir inséré une nouvelle entité). Une solution pourrait être de supprimer l'identité et d'utiliser le générateur d'identité HILO.


Ah oui, c'est une possibilité (et votre solution).


J'ai dit exactement comme Frederik, j'ai dû utiliser une CPBT (conversation par transaction par entreprise), car j'utilise le chargement paresseux. Je sais qu'aucun logiciel ne peut être tout pour tout le monde et NHibernate, je ne pouvais tout simplement pas être choisi plus tôt dans son cycle de développement de ne pas traiter de problèmes tels que ceux-ci.


7 Réponses :


0
votes

Si votre DAL est écrit sur une interface, il serait beaucoup plus facile de passer à NHibernate ou de quelque chose de compable (je préférerais fluent-nhibernate, mais je me digresse). Alors, pourquoi ne pas dépenser le temps à la fois refactoriser le DAL pour utiliser une interface, puis écrivez une nouvelle implémentation en utilisant NH ou votre orme de choix?


0 commentaires

1
votes

Pour moi, le meilleur ajustement était un concept assez simple - utilisez les définitions de classe DAO et avec la réflexion crée tout SQL nécessaire pour les peupler et les sauvegarder. De cette façon, il n'y a pas de fichier de mappage, seulement des classes simples. Mon DAO nécessite une classe de base de l'entité, donc ce n'est pas un poco mais qui ne me dérange pas. Il prend en charge tout type de clé primaire, que ce soit une colonne d'identité unique ou une colonne multiple.


2 commentaires

Utilisez-vous cela en combinaison avec un mappeur de métadonnées et / ou une mappeuse de données? Aussi comment gérez-vous des jointures ou des classes référencées?


@joshlrogères Aucun mappeur de données - chaque table est représentée par une classe DAO. Les jointures sont définies en mettant en œuvre une méthode GetJoin dans chaque DAO qui renvoie la déclaration de jointure appropriée en fonction des autres table (s). Chaque jointe DAO a une liste ou un objet pour la table jointe. Les jointures sont définies par des constructeurs en chaînage à la requête Time -Example: Liste = sql.read (SearchCriteria, Nouveau (produits (nouveaux commandes ())) Retourne une jointure entre produits et commandes.



0
votes

Dans les projets récents, nous avons cessé de programmer une DAL distincte.

Au lieu de cela, nous utilisons un mappeur relationnel objet (dans notre cadre d'entité de cas). Nous laissons ensuite le programme de la couche d'entreprise directement contre l'ormes.

Cela nous a sauvé plus de 90% des efforts de développement dans certains cas.


1 commentaires

C'est exactement pourquoi je voulais passer à NHibernate. Malheureusement, cela n'a pas fonctionné.



0
votes

Mon premier pas serait de casser le code d'un monstre de 15 kloc, puis de créer une stratégie de création d'une nouvelle DAL.


0 commentaires

1
votes

Mon expérience avec NHibernate est que, bien qu'elle soit emballée avec des fonctionnalités et très performantes, vous devrez éventuellement devenir un expert NHibernate afin de résoudre certains comportements inattendus. Lire à travers les réponses Pro-Nhibernate et voir

hmm, peut-être qu'il utilise une longue course à pied Sessions (session par entreprise Modèle de transaction), et dans un tel approche, utilisant l'identité est découragé, puisqu'il brise votre une unité de travail (il doit affleurer directement après avoir inséré une nouvelle entité). UNE la solution pourrait être de laisser tomber le identité et utiliser l'identité de Hilo Générateur.

illustre exactement ce que je veux dire.

Ce que j'ai fait est de créer une classe de base modélisée quelque peu du modèle Actionecord, que je hérite de et marquez la classe héritée avec des attributs qui l'attachent à une procédure stockée chacune pour sélectionner, insérer, Mettre à jour et supprimer. La classe de base utilise la réflexion pour lire les attributs et attribuer les valeurs de la propriété de la classe aux paramètres SP et, dans le cas de SELECT (), affecter les valeurs de colonne SQLDatreader de résultat aux propriétés d'une liste des génériques.

C'est ce que DataObjectBase ressemble à: xxx

Il s'agit d'un exemple de classe de données qui en dérive: xxx

i Sachez que cela semble être réinventer la roue, mais toutes les bibliothèques que j'ai trouvées avaient trop de dépendance à l'égard des autres bibliothèques (ActionCord + NHibernate, par exemple, qui était une seconde de près) ou étaient trop compliquées à utiliser et à administrer.

La bibliothèque que j'ai faite est très légère (peut-être quelques centaines de lignes de C #) et ne font rien de plus que d'affecter des valeurs aux paramètres et d'exécuter le SP. Il se prête également très bien à la génération de coder, de sorte que je m'attends à écrire aucun code d'accès aux données. J'aime aussi que cela utilise une instance de classe au lieu d'une classe statique, de sorte que je puisse transmettre des données à des requêtes sans une collection de critères inconfortables ou sans hql. Select () signifie "obtenir plus comme moi".


6 commentaires

Ceci est intéressant, c'est un peu verbeux, mais très intéressant. Votre stratégie permet-elle de la mise en cache?


Une dernière chose: cela fonctionne également avec une bibliothèque de Procs stockés existants. Il n'existe aucune exigence qu'ils soient nommés d'une certaine manière ou de noms ou commandes de paramètres non arbitraires.


Je suis un gars VB vieil école, Verbose est ma merde :) Il n'y a pas de mise en cache intégrée (encore). Je joue avec l'idée d'utiliser PostSharp pour mettre en œuvre la mise en cache AOP-style en interceptant des appels de méthode et de renvoyer des données en conserve. Pour l'instant, il y a des années-lumière devant le Raw Ado.net qu'ils faisaient.


Votre implémentation est très proche de ce que j'essayais ici. Pourquoi je me suis arrêté et je suis curieux de gérer cela, c'est que je me suis retrouvé à générer une multitude de procédures stockées très triviales. Je ne voulais pas vraiment avoir à passer à la quotidienne dans une liste de centaines de procédures stockées pour trouver celui que je cherche (même si le schéma de nommage est pratique.) Alors j'ai commencé à travailler sur un générateur SQL dynamique, mais j'ai commencé à courir dans Un problème conceptuel avec chargement profond et chargement paresseux. Avez-vous juste une tonne de SproCs? Quel est votre plan pour un chargement profond? Chargement paresseux?


L'organisation que je travaille est l'une de ces types de "tonnes de SproCs". Dans mon expérience, la plupart des organisations ont cessé d'innover à "Utiliser SPS pour l'accès aux données" et ont une énorme bibliothèque de SPS et une politique que les développeurs créent CRUD SPS pour chaque tableau de la base de données. Ce que j'ai fait, c'est utiliser un générateur (codesmith) pour tous les SP dont j'ai besoin pour chaque projet, alors je n'ai même pas à y penser.


En ce qui concerne le chargement profond / paresseux, je m'occupe de cela moi-même, à la main, où il se reproduit. Je charge des parties du graphique d'objet sur l'accès à la propriété. Mon adresse e-mail est chris.mccall@gmail.com. Si vous voulez, je peux vous envoyer tout ce genre de choses zippé.



0
votes

LINQ à SQL est agréable si vous utilisez SQL Server. Il y a une source là-bas pour un fournisseur LINQTOSQL pour accéder à MySQL. Je ne l'ai pas testé cependant. LINQTOSQL suit le modèle UNITOFWORD qui est similaire à la manière dont ADO.NET fonctionne. Vous établissez une série de modifications à une copie locale des données puis validez toutes les modifications avec un appel de mise à jour. C'est assez propre je pense.

Vous pouvez également prolonger la classe Datarow vous-même pour fournir un accès fortement typé à vos champs. J'ai utilisé XSLT pour générer les descendants de datarow basés sur les métadonnées de chaque table. J'ai un accord de données générique. Mydatable où T est mon rangée dérivée. Je sais que les jeux de données fortement typés de MS font une chose similaire, mais je voulais une version générique de poids léger que je contrôlais le contrôle. Une fois que vous avez ceci, vous pouvez écrire des méthodes d'accès statiques qui interrogent le DB et remplir le jeu de données.

Vous seriez responsable de la rédaction des changements du DataTable Retour à la DataSource. J'écrirais une classe générique ou une méthode qui crée la mise à jour, les insertions et les suppressions.

bonne chance!


0 commentaires

0
votes

J'utilise l'emballage de la mine pour SPS pour la récupération de données la plus rapide et la L2S lorsque la performance n'est pas un objectif. Mon dal utilise le motif de référentiel et la logique encapsulée pour TDD.


0 commentaires